Repository navigation
Open Questions
Numbered so they can be referenced from other pages and from issues. Anything resolved here graduates to an ADR in Decisions and stays listed below with its answer, so the reasoning is not lost.
Separate discussion — deliberately not decided as part of the initial scope.
JVM startup cost is paid on every invocation, which is exactly the wrong shape for a CLI used interactively, in shell completion and in loops over a CSV. A native image would give near-instant startup and a single binary with no JRE requirement.
Against it: an additional and considerably slower build, per-platform build infrastructure (macOS arm64/x64,
Linux, Windows), and reflection configuration for everything reflective — picocli, JAXB-generated data types,
XML signature handling, the JCE/TLS stack and DNS resolution are all candidates for trouble. Some of those are
notoriously awkward under native-image.
No project in this ecosystem currently builds a native image, so this would be new ground.
Sub-questions: is native image an additional artefact or the primary one? Which platforms are supported? Does
the effort still pay off given Java 25's ahead-of-time class loading and linking (see ADR-005)?
> TODO(verify): measure plain JVM startup for a trivial command before treating startup time as a problem worth this much effort
Candidates and the trade-off are set out in Configuration: TOML (readable, comments, typed, new dependency), Java properties (no new dependency, ecosystem-native, poor at nesting), YAML (familiar, but whitespace-sensitive and easy to get subtly wrong), JSON (no comments — disqualifying for a hand-edited file).
Depends on: which dependency is acceptable, and whether profiles need nesting deeper than one level.
> TODO(verify): whether the ph-commons configuration facility already provides a suitable file format and precedence handling that should simply be reused
See ADR-006. Consistent with norma-cli, kaltblut-cli,
ph-redact-cli, the en16931-*-cli tools and phoss-peppol-mcp (picocli 4.7.7).
Remaining detail: pin the version locally or inherit it from a shared parent POM property.
Parsing and pretty-printing an MLS response is clearly useful for diagnostics and is low-risk.
Generating one is a different matter: an MLS response is a statement made by a receiving party about a message it processed. A CLI that can emit one invites hand-crafted statuses being sent outside the AP that actually handled the message, which is a correctness and accountability problem rather than a convenience.
Options: (a) parse only, (b) parse plus generate behind an explicit "for testing" flag, (c) parse plus full
generation. Current inclination is (a), with (b) as a compromise if there is real demand from implementers
testing their own MLS handling.
> TODO(verify): the exact MLS specification name and version, and whether generation has a legitimate stand-alone use case in practice
The code lists are bundled in the distribution, so the tool works offline. The question is what happens when they go stale.
Options: (a) bundled only, updated by upgrading the tool — simple, predictable, but ties code list currency to
the release cadence; (b) bundled plus peppol codelist update fetching a published artefact into the user cache
— needs a stable, authoritative download location and signature verification; (c) automatic background refresh
with a TTL — convenient, but makes an unattended run's behaviour depend on the network and on timing, which is
the wrong trade for CI.
Current inclination: (a) for M1, (b) later, never (c) without an explicit opt-in. Related: should the tool warn
when its bundled code lists are older than some threshold?
> TODO(verify): whether the Peppol code lists are published as a versioned, downloadable artefact suitable for automated retrieval, and how that source is authenticated
See ADR-005. Note that the shared parent POM currently defaults to
Java 17, so this project overrides the java.version property.
Remaining detail: whether the distribution archive should bundle a runtime (via jlink) so users do not have to
install Java 25 themselves.
Apache License 2.0 is proposed, for consistency with the other projects in this ecosystem. The repository
already contains an Apache 2.0 LICENSE file.
> TODO(verify): confirm Apache 2.0 is intended for this project, and check the licences of all planned dependencies for compatibility — picocli is Apache 2.0, but every transitive dependency should be reviewed once the dependency set is fixed
Options: (a) tier 1 — tested in CI, .cmd/.ps1 launcher, PowerShell completion, Windows path and console
handling, %APPDATA% config location; (b) best effort — it should work, but is untested and unsupported;
(c) not supported.
Specific Windows concerns: ANSI colour support in the console host, %APPDATA% versus XDG config discovery,
path separators in bulk CSV input, keystore access, and whether the Windows certificate store should be used as
a truststore source.
Current inclination: (a), because support engineers are a target audience and frequently work on Windows.
> TODO(decide): confirm the intended support level, since it determines CI cost from the start
Typing a 200-character document type identifier is the single worst part of the current tooling experience, so aliases are clearly worth having. The question is where they come from.
Derived from code list display names — free, always complete, and automatically covers new document types.
But verified problems: 16 of the 321 display names in v9.7 are duplicated (mostly busdox-docid-qns versus
peppol-doctype-wildcard variants), and display names are not guaranteed stable across code list versions. An
alias that silently changes meaning after an upgrade is worse than no alias.
Curated in the CLI — a hand-maintained table of short, stable names (bis3-invoice, bis3-creditnote) for
the dozen or so document types people actually type. Stable by construction and unambiguous, but needs
maintenance and will not cover everything.
Both — a curated table taking precedence, falling back to derived display names, with ambiguity always an
error rather than a guess. Probably the right answer; it needs a decision on who maintains the curated table and
whether it belongs in peppol-commons rather than in the CLI, since the problem is not CLI-specific.
See the alias rules in CLI Conventions and the feature entries in Feature Catalogue.
These came out of drafting and need an owner:
-
Default network. Should
--networkhave a default at all? Defaulting toprodrisks accidental production writes; defaulting totestrisks confusing read-only users; requiring it always is safest but verbose. Possible compromise: required for write commands, defaulted for read commands. -
Write command safety. Is
--dry-runthe default for write commands, with--committo execute? -
Command naming for the flagship check.
peppol smp can-receivereads well; is there a more conventional name for what operators actually call this check? - JSON Schema publication. Publish a schema per command, or document the shapes in the wiki only?
- Telemetry. Proposed answer: none, ever, with no opt-in. Worth recording as an ADR so it is never revisited casually.
- Deprecation handling. Does using a deprecated participant scheme or document type warrant a warning at exit 0, or its own exit code?
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