Repository navigation
Plugin dependencies follow the plugin's own security policy; Hermes's 14-day quarantine applies to Hermes deps only (reverses #118841 item 3, unblocks #120076 #114530) - #120231
Merged
Conversation
teknium1
force-pushed
the
plugin-dep-policy
branch
from
September 23, 2026 13:13
4d4575b to
c2bc18a
Compare
…licy Hermes's 14-day `[tool.uv] exclude-newer` quarantine applies to Hermes's own dependencies only (uv lock/sync, `hermes update`, LAZY_DEPS extras via `ensure()`). A plugin's declared `python_dependencies` install under the PLUGIN's policy: `install_specs(policy="plugin")` runs uv with `--no-config` from any cwd, still inside the core constraints file. Reverses item 3 of #118841, which ran the uv tier with cwd=<checkout> for every install so the quarantine reached plugin deps from any cwd. That made catalog re-pins floored on a <14-day release uninstallable (#120076: "only hindsight-client<=0.9.2 is available"; #114530 held on the same gate). Maintainer ruling (Teknium): "plugins dont have to abide by our 14 day rule btw. They can have their own security policy on that. Only hermes' dependencies themselves have to. We should recommend that they do this for their plugins and we should give guidance to plugin devs that they should though." - tools/lazy_deps.py: INSTALL_POLICIES ("core" | "plugin"); `_uv_policy_args` replaces `_uv_policy_cwd`; `_venv_pip_install(policy=)` defaults to core (ensure/LAZY_DEPS), `install_specs(policy=)` defaults to plugin. - hermes_cli/plugin_python_deps.py: `resolve()` passes policy="plugin". - Docs: developer guide "Dependency security policy" section, catalog README admission rule 9, AGENTS.md pinning policy — plugin authors are responsible for their deps and strongly recommended to pin upper bounds, floor on the oldest API-compatible version and run their own release quarantine (`uv --exclude-newer` in their CI); operators can set UV_EXCLUDE_NEWER. - Tests: the #118841 cwd test is replaced by two invariants — a plugin install carries `--no-config` and no checkout cwd (red on base), a core lazy install keeps the checkout cwd and no `--no-config`.
teknium1
force-pushed
the
plugin-dep-policy
branch
from
September 23, 2026 17:00
c2bc18a to
cf931e5
Compare
૮ >ﻌ< ა ci reviewran on cf931e5 — chore: retrigger CI (zero-job dispatch failure, auto-heal)
|
15 of 17 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plugin
python_dependenciesnow install under the plugin's own dependency-security policy; Hermes's 14-dayexclude-newerquarantine applies to Hermes's own dependencies only — so catalog re-pins floored on a fresh release (#120076 hindsight 1.0.1 →hindsight-client>=0.10.1) install again, whilehermes update/ lazy extras stay quarantined.Reverses item 3 of #118841 (merged 74f726c), which pinned the uv tier's cwd to the checkout for every install so the quarantine reached plugin deps from any cwd. Maintainer ruling:
Changes
tools/lazy_deps.py— the line is drawn in code, not by cwd tricks:INSTALL_POLICIES = ("core", "plugin")._uv_policy_args(policy)replaces_uv_policy_cwd():coreruns uv from the checkout root (quarantine +exclude-newer-packageexceptions apply from$HOME, a service, the Desktop backend);pluginpasses--no-config(no project file discovered from any cwd; env knobsUV_INDEX_URL/UV_EXCLUDE_NEWERstill apply, so an operator can quarantine plugin deps themselves)._venv_pip_install(policy=)defaults tocore(ensure()/ LAZY_DEPS extras);install_specs(policy=)defaults toplugin— every caller ofinstall_specsinstalls plugin/provider-manifest deps (plugin_python_deps.resolve→ CLI install/enable/update, catalog installs, dashboard memory-provider setup,hermes memory setup, post-updatereapply_all, memory-provider migration, mem0/honcho SDK self-installs). The core constraints file still bounds plugin resolution.hermes_cli/plugin_python_deps.py—resolve()passespolicy="plugin"explicitly.pyproject.toml[tool.uv],uv lock/syncinmanaged_uv, the exact-pin/upper-bound lint intests/test_packaging_metadata.py.website/docs/developer-guide/plugins/index.md— new Dependency security policy section: Hermes does not quarantine plugin deps; plugin authors are responsible for their own deps and strongly recommended to pin upper bounds, floor on the oldest API-compatible version, adopt their own new-release quarantine (uv --exclude-newer "14 days"/UV_EXCLUDE_NEWERin their CI), review bumps; the catalog review reads the dependency list at the pin.plugin-catalog/README.md— admission rule 9: dependency policy is the plugin's; reviewers recommend (not require) bounds + oldest floor + own quarantine; a recent floor alone is not grounds to hold an entry.AGENTS.md§ Dependency Pinning Policy — scope of the quarantine and the ruling, with the code seam named.hermes-plugin-catalog-intake) — the stale "quarantine applies to plugin installs from any cwd, hold until it ages" rule replaced by the ruling + recommend-not-require guidance.uv tier runs from the checkout) is replaced by two invariants intests/tools/test_lazy_deps.py: a plugininstall_specscall carries--no-configand no checkout cwd (red on base, green fixed); a coreensure()install keeps the checkout cwd and no--no-config(control, green both sides).Validation
hermes plugins install vectorize-io/hindsight#hindsight-integrations/hermes --ref f7a153dd…(fresh scratch venv, fakeHOME/HERMES_HOME, cwd=$HOME)Because only hindsight-client<=0.9.2 is available and you require hindsight-client>=0.10.1,<1 … filtered by exclude-newer(the #120076 symptom)✓ Plugin installed,hindsight-client==0.10.1in the venv_venv_pip_install(("hindsight-client>=0.10.1,<1",), dry_run=True, policy="core")from$HOMEfiltered by exclude-newer to only include packages uploaded before 2026-09-09— Hermes's quarantine holds from any cwd… policy="plugin"+ hindsight-client==0.10.1uv pip install --dry-run --show-settingsfrom checkout / checkout--no-config/$HOME14d/ — /None14d/None/None(--no-configdeterministic from any cwd;UV_EXCLUDE_NEWER="7 days"under--no-config→7d)tests/tools/test_lazy_deps.pynew plugin invariantscripts/run_tests.sh tests/tools/ tests/hermes_cli/test_plugin*.py …Live repro: before —
HOME=<scratch>/fakehome HERMES_HOME=… python -m hermes_cli.main plugins install vectorize-io/hindsight#hindsight-integrations/hermes --ref f7a153dd9050e800cb295fd278f0a3ed0af29f32exits 1 with theexclude-newerrefusal; after — same command exits 0 and installshindsight-client 0.10.1; core dry-run underpolicy="core"from the same cwd still refuses.Root cause in one sentence: #118841 applied a project-scoped uv policy to installs that are not the project's, by making cwd carry the policy for every install.
Trade-off noted:
--no-configalso skips a user-level~/.config/uv/uv.tomlfor plugin installs (env vars such asUV_INDEX_URLstill apply; pip.conf/PIP_INDEX_URLare bridged already). A--project <dir>alternative preserved user config but walks up the directory tree and is not deterministic.Unblocks #120076 and #114530 (the re-pins land once this merges). Follow-up to #118841.
Infographic