Repository navigation
Requirements
Normative requirements for peppol-cli, using the RFC 2119 keywords MUST, MUST NOT, SHOULD, SHOULD NOT and MAY.
Requirement IDs are stable: once assigned, an ID is never reused or renumbered, and a withdrawn requirement is
marked as such rather than deleted.
Status of this page. This page currently specifies the update check only. Other areas of the tool are described in prose in Feature Catalogue, CLI Conventions, Configuration and Architecture; they will gain their own requirement sections and ID prefixes when they are formalised, which is why the IDs here are confined to
UPD.
The tool checks whether a newer release exists. The design constraint throughout is that this convenience must never cost the user anything — not latency, not output cleanliness, not privacy.
| ID | Requirement |
|---|---|
| UPD-01 | The tool MUST check for a newer release at most once per 24 hours. The time of the last check MUST be stored in a state file under ~/.cache/peppol/, or the platform equivalent. |
| UPD-02 | The check MUST be a single HTTPS GET to a configurable URL. The default MUST be https://<host>/peppol-cli/latest.json. |
| UPD-03 | The response MUST be JSON containing at least latestVersion and releaseUrl, and MAY contain minSupportedVersion and message. See Response schema. Unknown members MUST be ignored. |
| UPD-04 | The check MUST NOT delay command execution. It MUST run concurrently with the command, MUST use a timeout of 2 seconds, and MUST fail silently. Network errors MUST NOT affect the command output or its exit code. |
| UPD-05 | If a newer version exists, the tool MUST print a one-line notice to stderr, after the command output, and only when stderr is a TTY. It MUST NOT write to stdout under any circumstance, so that --output json pipelines stay clean. |
| UPD-06 | If the running version is below minSupportedVersion, the notice SHOULD be emphasised. The command MUST still execute normally. |
| UPD-07 | The request MUST contain no data beyond the User-Agent, which MUST have the format peppol-cli/<version> (<os-name>; <os-arch>; Java <feature-version>[; CI]). The CI token MUST be added when the CI environment variable is true. |
| UPD-08 | The request MUST NOT contain identifiers of any kind: no participant, document type or process identifiers, no SMP or SML URLs, no file names, no host names, and no persistent installation ID. |
| UPD-09 | The check MUST be disabled when any of the following holds: the configuration key updatecheck.enabled is false; the environment variable PEPPOL_NO_UPDATE_CHECK is 1; the environment variable DO_NOT_TRACK is 1. |
| UPD-10 |
peppol --version MUST perform an immediate check, ignoring the 24-hour limit of UPD-01 but still respecting UPD-09, and MUST print the result. |
| UPD-11 | All outgoing HTTP requests — SMP, SML, Phorm, Directory and the update check — MUST use the User-Agent format defined in UPD-07. |
| UPD-12 | The configuration MUST support updatecheck.enabled, defaulting to true, and updatecheck.url, defaulting to the URL of UPD-02. |
| UPD-13 | The behaviour of the update check and the data it transmits MUST be documented in the README and in peppol --help. |
| UPD-14 | The response MAY contain nssListVersion and nssListLastUpdate, describing the Mozilla NSS root certificate list bundled in the latest release. When present, and when the running build's own list is older, the notice SHOULD say so. This MUST NOT replace the local staleness check, which has to work with the update check disabled. |
The document returned by the URL of UPD-02:
| Member | Type | Presence | Meaning |
|---|---|---|---|
latestVersion |
string | MUST | The newest released version, in the project's own version format. |
releaseUrl |
string | MUST | An absolute https URL where that release can be obtained. |
minSupportedVersion |
string | MAY | The oldest version still supported. Triggers the emphasised notice of UPD-06. |
message |
string | MAY | A short free-text note to show alongside the notice. |
nssListVersion |
string | MAY | The Mozilla NSS root certificate list version bundled in the latest release, e.g. "2.93". See UPD-14. |
nssListLastUpdate |
string | MAY | That list's last-update date, as YYYY-MM-DD. |
{
"latestVersion": "1.4.0",
"releaseUrl": "https://github.com/phax/peppol-cli/releases/tag/v1.4.0",
"minSupportedVersion": "1.2.0",
"message": "1.4.0 fixes SMP redirect handling.",
"nssListVersion": "2.93",
"nssListLastUpdate": "2026-12-01"
}Consequences of UPD-03 worth stating explicitly: a response that cannot be parsed, or that omits a MUST member,
MUST be treated exactly like a network error under UPD-04 — silently ignored. message is server-controlled free
text, so it MUST be printed as a single line with control characters stripped, and MUST NOT be interpreted as
markup or as a command.
| ID | Requirement |
|---|---|
| UPD-S-01 | The endpoint MUST derive only the country code from the client IP address, at the edge, and MUST NOT persist IP addresses. |
| UPD-S-02 | Stored data MUST be limited to: the timestamp, for which day granularity is sufficient; the country code; and the parsed User-Agent fields of UPD-07, namely version, OS name, architecture, Java feature version and the CI flag. |
| UPD-S-03 | Stored data MUST only be evaluated in aggregate. |
| UPD-S-04 | The behaviour of the endpoint MUST be described in a privacy note linked from the README. |
Taken together, UPD-07, UPD-08 and UPD-S-01 to UPD-S-03 mean the server cannot distinguish two installations in the same country running the same build, by construction rather than by policy. That is the property the privacy note of UPD-S-04 should state, because it is what a reader actually wants to know.
Worth stating what these do and do not buy, because the obvious reading overstates them.
What they add: a better reason, and a second remedy. Learning that the latest release carries 2.93 while
this build carries 2.90 sharpens the recommendation considerably — "upgrade: your trust data is three versions
behind" is materially more persuasive than "upgrade: a newer version exists", and it lets a user judge whether
the lag matters to them. It also no longer leads only to an upgrade: because the trust list can be
overridden locally when the local copy is newer, a user who cannot
upgrade right away has a second way out. Both are worth naming in the notice.
Compare against the effective list. UPD-14 says "the running build's own list"; with a local override in play
that means the list the CLI actually resolved, which is not necessarily the compiled-in bundle. A user who has
provisioned 2.95 locally while the latest release bundles 2.93 is not behind at all, and the remark has to be
suppressed rather than inverted. The notice should also name the source it compared, for the same reason the TLS
check does — otherwise "your trust data is behind" is unactionable advice about a file the user may not know is
being used.
Why they cannot replace the local check. The update check is disabled by any of three switches (UPD-09), and is skipped entirely when offline. A user who has opted out would then get no staleness signal at all. So the local six-month threshold stays as the baseline, and these fields refine the message when they happen to be available.
A release-process coupling to get right. The values must be derived from the released artifact rather than
maintained by hand, or latest.json will eventually claim a list version the latest release does not actually
contain — and the client would then report a lag that does not exist. Generating them at release time from the same
source as the bundle is the only safe arrangement.
Blocked on the same library gap either way. The client must know its own list version to compare against, and
MozillaNSSTrustStore does not expose one — see Library Gaps. Without that, these fields have
nothing to be compared with.
UPD-11 is the one with reach beyond this feature. A single User-Agent format across every outgoing request makes
peppol-cli traffic recognisable in the server logs of the services this project operates, which helps both
support and capacity planning. It is stated here because UPD-07 is where the format is defined; if a general
requirements section is added later it belongs there, with UPD-11 retained as a cross-reference rather than
renumbered.
UPD-12 is already reflected in Configuration, so the configuration surface stays complete.
Nothing further is needed for showing these settings: that page already specifies that peppol config show
prints every effective setting with its source and with secrets masked, which covers these keys without naming
them — verified, rather than assumed.
UPD-13 matters more than a documentation requirement usually would. A tool that makes an unprompted network
request has to say so somewhere the user will actually look, and --help is that place. Describing it only in a
privacy note nobody opens would satisfy the letter of UPD-S-04 and miss the point.
peppol-cli — licensed under the Apache License, Version 2.0.
Not an official OpenPeppol tool. This is an independent open source project and is neither endorsed by nor affiliated with OpenPeppol AISBL. "Peppol" is a trademark of OpenPeppol AISBL.
Status: planning
Overview
Design
Decisions
Reference