An official plugin's version should say which Postulo it is for, and requires_postulo is never checked #186
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#186
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The rule
An official plugin's version tracks the core's. postulo-mcp 0.3.0 is the one that works
with Postulo 0.3.0; so is postulo-paperless 0.3.0, and every other plugin the project
publishes. Somebody who knows which Postulo they run knows which plugin to install, without
reading a compatibility table.
This is not a new idea here — it is already the rule for the built-ins, written down in
plugins/base.pywith its reasoning:test_plugin_manifests.pyenforces it for built-ins today: a manifest whose version is notpostulo.__version__fails. What this issue does is extend the same reasoning outward, tothe plugins that ship in their own repositories.
Where everything actually is
package.json, notpyproject.tomlpackage.jsonEvery one is 0.1.0 and none has ever been released, so nothing has to be migrated — the rule
can simply start.
The field exists and nothing enforces it
catalogue.pyalready carries per release:and the module docstring already promises it:
It is parsed at
catalogue.py:200, stored onRelease, set by a fixture intest_plugin_install.py:341— and never compared to anything. The docstring lists thechecks that are fatal:
Compatibility is not among them. A release declaring
requires_postulo: ">=0.5"installsinto 0.3.0 today, and the first anyone knows is an ImportError in a log.
The version scheme, and the cost of getting it wrong
Strict full lockstep is a trap. If postulo-mcp must be exactly 0.3.0 to pair with core
0.3.0, then every core release forces a release of all eight plugins whose code did not
change, and a plugin bugfix cannot ship at all without a version claiming a core release
that does not exist.
Lockstep on major.minor, free patch gives the rule its whole benefit and none of that:
So
requires_postulofor an official plugin is~=0.3.0— the minor is the contract, thepatch is the plugin's own. That reads the same way to a person ("0.3 plugin, 0.3 Postulo")
and lets each repository fix its own bugs.
What to do
CONTRIBUTING.mdand in the wiki's Writing a plugin, which today showsversion = "1.0"in its examples and says nothing about pairing.
requires_postuloat install, and make it a fourth fatal check beside the otherthree, with a refusal that names both versions. A plugin that declares nothing keeps
installing — the field is optional and a third-party plugin may reasonably not know.
should be visible there, not only at import time. This meets #184, which is already
redrawing those tags.
been published, so this costs one line per repository and no migration.
package.json, notpyproject.toml, and they are not installedthrough the catalogue at all — they go through a browser store. The rule still applies to
the number a person sees; the enforcement cannot.
rest or deliberately not; either answer is fine, silence is not.
Related
v0.1.0. Underthis rule it is
v0.3.0. Updated there.Decided: the lock is on the major
Not
~=0.3.0as the issue proposed. What is enforced is the major:A plugin declares the floor it needs and keeps working across core's minors until the next
major. The number it carries still tracks the core it was released beside — postulo-mcp
0.3.0 ships with Postulo 0.3.0 — so a person can still pair them at a glance; what changed is
that the installer no longer refuses a 0.3 plugin on core 0.4.
One consequence to be aware of, because 0.x is not 1.x
Semantic versioning puts every
0.xin the same major, so a major-only lock during 0.x is afloor and a ceiling at 1.0 and nothing in between. That is genuinely loose while Postulo is
pre-1.0, because 0.x is exactly where breaking changes land in the minor — a plugin
written against 0.3's plugin API will install happily on 0.6.
That is a reasonable trade while nothing has shipped and both sides move together, and it
becomes the right rule the moment Postulo is 1.x. It is worth knowing rather than
discovering: a plugin that a core release actually breaks has to raise its own floor
(
>=0.6) and say so in its changelog, and that is the mechanism, not the installer.Everything else in the issue stands — the field is parsed and never checked, and that is
still the thing to fix.
Every plugin carries its own catalogues, and that now includes the release sweep
Core never translates a plugin's strings. Where the plugins actually are:
fr_FR,pt_PT(English is the source)The five Python plugins are already at exactly the three languages #182 just made the working
standard, which is a happy accident worth making deliberate.
What #182 means for these repositories. Core now translates English, French and European
Portuguese day to day and sweeps up the twenty-four European Union catalogues at a release,
behind
uv run pytest -m release. That gate lives in core's suite and cannot see aplugin's catalogues — the plugin-locale rule guarantees it. So each official plugin needs
the same gate in its own suite and the same line in its own release checklist, or the rule
quietly means "plugins are never fully translated". postulo-chromium's 39 show the intended
end state; the Python plugins' two show the working state.
postulo-mcp is the one that needs a decision rather than a catalogue. Its user-facing
strings are tool descriptions and prompts read by a model, not a person, and translating
those is at best pointless and at worst harmful — an agent reasoning over a French tool
description while the person writes English. Its README and its command-line messages are a
different matter. Decide which of the two it has, and if the answer is "no catalogue at all",
write that down in the repository so nobody adds one out of consistency.
Landed across the repositories.
Core —
ca99644bc,6e73da0c5,3d1f44a36onmain:requires_postulois the third fatal check, before the download, with a refusal naming both versions; what a release declared is recorded with the plugin and asked again on every visit to Server → Plugins, which marks a plugin that no longer fits for Postulo … and shows a catalogue listing that does not fit its reason instead of an Install button;packagingdeclared as a dependency; the versioning rule written inCONTRIBUTING.md(Versions of official plugins) and in the wiki's Writing a plugin.Each official repository took its number, 0.3.0, as decided: postulo-helloworld
9397274, postulo-imap23cef46, postulo-apprise57a5e91, postulo-davb15b164, postulo-paperless9c05133, postulo-mcpface8f4, postulo-chromium08774a2(package.json and the source manifest), postulo-firefox7d22ee2. postulo-templates says in its README that it carries no version and why (01b8ae2).postulo-dav and postulo-paperless were also brought to work against the current core on the way (their #1 each), since the pin had to move for the catalogue gate to run at all.