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
Code lists ship with the distribution and are updated by upgrading the tool. No download, no cache refresh, no TTL.
This follows from the data's shape rather than from preference: the code lists are exposed at runtime only as
generated enums, and there will be no shared library for reading code list data at runtime. peppol codelist diff
and peppol codelist update are therefore rejected in the Feature Catalogue.
The upside is real: every code list command works offline, unconditionally, with nothing to invalidate and no
unattended run whose behaviour depends on a background download. peppol codelist version reports the bundled
version per kind, so a user can always see what they have — and each code list is versioned independently, so
the versions are allowed to differ and the tool must not treat that as an error.
Remaining minor question: should the tool warn when its bundled code lists are older than some threshold? That
needs no new mechanism, only a build-time timestamp. > TODO(decide): warn on stale bundled code lists, or leave it to the user to notice?
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.
SMP 1.4.0 §3 defines no create/update/delete interface, so the write API peppol-smp-client speaks is in practice
the phoss-SMP one. Rather than hide that behind a generic smp area, the write commands live under their own
phoss-smp area — see CLI Conventions and the
Feature Catalogue. peppol smp … stays the specified read interface that works against any
conformant SMP.
That makes the portability boundary visible instead of documented-in-a-footnote, and leaves room for a future
peppol <other>-smp area without renaming anything. Other implementations that happen to expose the same API are
likely to work, but the tool promises nothing about them.
Remaining detail: > TODO(decide): the area spelling — phoss-smp or phosssmp — and whether the tool should detect an incompatible SMP up front rather than failing part-way through.
These came out of drafting and need an owner:
-
Default network.Resolved:--networkdefaults toprod. Almost all use is looking up real participants, so production is what the user meant;--network testis the deliberate act. The consequence is that write safety rests entirely on the write rails — confirmation,--dry-run, and naming the resolved network in the prompt — rather than on the network selector. See CLI Conventions. -
Write command safety. Is
--dry-runthe default for write commands, with--committo execute? This matters more now that the network defaults toprod. -
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