ADR-0001: RH plugin manifest dependency format¶
Status¶
Accepted (2026-04 — see also the source document
../../rh-plugin/docs/manifest-dependency-format.md
which preceded this ADR formalisation).
Context¶
RaceLink_RH_Plugin declares its dependency on RaceLink_Host in
custom_plugins/racelink_rh_plugin/manifest.json. That manifest
is validated by RHFest, the validator that gates RotorHazard
plugin manifests in the official store.
RHFest v3 accepts dependency entries in only two shapes
(implemented in RotorHazard/rhfest-action under rhfest/const.py,
consumed by rhfest/checks/manifest.py):
- a package name with an optional version specifier, e.g.
racelink-host==0.1.0; - a
git+https://...URL with an optional@<tag>suffix.
RaceLink_Host is not published on PyPI. A direct PyPI dependency
would not work. A direct wheel-URL dependency in PEP-508 form
(racelink-host @ https://example.invalid/racelink_host-1.2.3-py3-none-any.whl)
is rejected by RHFest's validator.
The plugin maintainer also wants the choice to be reproducible:
the spike scripts/verify_manifest_dependency_formats.py runs the
same RHFest validator locally so a contributor can confirm any
change before opening a PR.
Decision¶
For online installations, the plugin uses:
The @v<version> suffix is an immutable Git tag, pinned per
plugin release. Local development and CI use the same pinned
host version, but consume it through the immutable GitHub-release
wheel URL declared in pyproject.toml (because racelink-host is
not on PyPI).
For offline installations, the manifest's dependencies field is
cleared in the offline-release ZIP so RotorHazard does not try
to fetch packages during installation. The bundled wheel under
custom_plugins/racelink_rh_plugin/offline_wheels/ is installed
locally on the first plugin start, after which the plugin loads
normally from the RotorHazard Python environment.
Consequences¶
- Reliable RHFest validation. Both shapes (package-name with
version specifier and
git+https://) pass; the plugin uses the Git URL becauseracelink-hostis not on PyPI. - Immutable references only. A floating
git+https://...@mainreference is rejected by policy; only an immutable tag may be used. - Online and offline both work. The two installation modes resolve to the same host wheel for a given plugin release — online fetches it during install, offline ships it inside the ZIP.
- No PEP-508 wheel-URL form. A direct
racelink-host @ https://...whlreference must not be used unless RHFest broadens its dependency validation rules. The spike test (verify_manifest_dependency_formats.py) regression- guards this rule. - Version coupling per release. Each plugin release pins one
immutable host tag; the version-mapping is documented in the
release playbook
(
../../rh-plugin/docs/release-playbook.md). - Future PyPI publication of
racelink-host— if the host is later published on PyPI, the plugin can switch toracelink-host==<version>with a single manifest edit. This ADR would then move to Superseded with a successor ADR documenting the switch.