Skip to content

Requirements

Philip Helger edited this page Oct 8, 2026 · 3 revisions

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.

Update check

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.

Client side

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.

Response schema

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.

Update check endpoint (server side)

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.

On the NSS list fields

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.

Notes on three of these

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.

Clone this wiki locally