Changelog
All notable changes to Peppy will be documented on this page.
Subscribe to the Atom feed for updates.
v0.27.8 (Alpha): Consumed-topic schemas are now generated one file per slot, so two same-named topics with different message formats each decode correctly.
Breaking changes
-
Consumed-topic Cap'n Proto schemas are now generated one file per slot, keyed as
on_next_<link_id>_<topic>instead of per topic name; regenerate and rebuild your node bindings after upgrading. -
You can now consume two same-named topics from different producers even when their message formats differ, because each slot decodes through its own schema instead of whichever one was registered last.
v0.27.7 (Alpha): The generated test harness can now make the node under test the launch's source of simulated time, publishing its own clock.
- Pass
sim_time_participantswithuse_sim_timein the test harness to make the node under test the launch's source of simulated time, so it publishes its own clock instead of the test ticking.
v0.27.6 (Alpha): Peppy authenticates git over SSH using the agent and identity files your ~/.ssh/config selects per host, so 1Password, Secretive, and gpg-agent work.
- Git over SSH now authenticates with the agent and identity files
~/.ssh/configselects for each host throughssh -G, honoring yourHost,Match,Include,IdentityAgent, andIdentityFilesettings. - The daemon binds the agent your
IdentityAgentnames once at startup and logs which one, making 1Password, Secretive, and gpg-agent reachable even from a service installed withpeppy service install. - SSH credential failures now name the agent socket, the identity files offered, and any configured paths that do not exist, so a typo in
~/.ssh/configis visible in the message.
v0.27.5 (Alpha): node build and stack launch now reuse a cached artifact for unchanged sources, with --rebuild to force a fresh build.
Breaking changes
-
Built node artifacts now live at
~/.peppy/built_nodes/<name>_<tag>/<fingerprint>.tar.zst(or.sif) rather than~/.peppy/built_nodes/<name>_<tag>.tar.zst; update any scripts that reference the old fixed path. -
peppy node buildreuses a stored artifact when the staged sources are byte-identical to an earlier build's, skippingbuild_cmdorapptainer buildand loggingReusing cached build of .... -
The cache is a content-keyed directory tree that survives daemon restarts and carries built nodes to any machine booted from the same disk with a matching peppy version, OS, and architecture.
-
peppy stack launchreuses cached builds for every deployment, on the coordinator and on every peer, so relaunching the same launcher skips rebuilding unchanged nodes. -
Pass
--rebuildtopeppy node buildorpeppy stack launchto rebuild from the staged sources even when a matching artifact exists, replacing it; this is independent of--force.
v0.27.2 (Alpha): `peppy repo add` gains an `--id` flag to register a repository under an exact id from the reserved `>= 2000` band.
peppy repo add --id <id>pins a new repository under an exact id from the reserved band (>= 2000) instead of a derived one, so setups that re-register it keep a stable id.
v0.27.3 (Alpha): Peppy now reads git repositories over SSH, so private repositories are reachable without embedding a credential in your config.
- You can now give
peppy repo add,peppy node add, andgitentries inrepositories.json5an SSH URL (git@host:owner/repo.gitorssh://) to reach a private repository, authenticating through your ssh-agent and~/.sshkeys the waysshdoes.
v0.27.4 (Alpha): A launch can name one instance its simulated-time source, fed to every machine, with one clock source enforced across the fleet.
Breaking changes
-
In Rust, read a clock tick's instant with
tick.time()instead of thetick.timefield; Python keeps the.timeattribute. -
Reading simulated time now requires a daemon that serves it, so an instance with
use_sim_time: trueis refused on a wall-mode daemon instead of running; start it with--clock-source=sim. -
Declare one launch instance its simulated-time source with
framework: { publishes_sim_time: true }; peppy hands itsSimTimePublisherevery machine of the launch so one clock reaches the whole fleet. -
Federated launches require every machine to serve the same clock source; a sim/wall disagreement is refused at preflight, naming the machine and the flag that fixes it.
-
A launch may declare only one simulated-time source; a second is refused when the launcher is checked, including by
peppy stack resolve. -
Launch feedback names the simulated-time source, and warns when a declared source runs on a wall launch or when a simulated launch declares none.
v0.27.1 (Alpha): `peppy repo show` now reports each pairing slot a node declares alongside the indexed nodes that could fill it.
peppy repo show <node>:<tag>now ends with one section per pairing slot the node declares, listing the indexed nodes that could fill it by playing the pairing's other role, and saying so when none can.- The
--jsonoutput ofpeppy repo shownow carries apairing_slotsarray in each report, each entry giving the slot'slink_id,pairing,role,optional, and thepeersthat could fill it.
v0.26.3 (Alpha): Adds `peppy repo search` and `repo show` to find any indexed item by regex and report who implements, consumes, or observes it.
Breaking changes
- A bare launcher name (no path separator, no
.json5) passed topeppy stack launchorstack resolvenow resolves through the repository cache only, never a same-named file in the current directory; write./name.json5to launch a local file. - Run
peppy repo refreshafter upgrading: peppy refuses a nodes cache written by an earlier release, and the commands that read it fail until it is rebuilt.
Repository search and inspection
peppy repo search <name-regex>[:<tag-regex>][@<sha256>]finds any indexed node, launcher, contract, pairing, or MCP exposure by unanchored regex, listing each match's kind, repository, path, and fingerprint.peppy repo show <query>reports every matched identity: where each document is published and, for a contract or pairing, the nodes that implement, consume, participate in, or observe it, with each pin's status.- Both
repo searchandrepo showaccept--jsonfor machine-readable output and read the local caches, so they need no daemon.
Other improvements
peppy stack list --jsonprints the discovered core nodes and their stacks as one JSON document.stack listpanels and therepo search/repo showtables now fit the terminal, wrapping over-long cells inside the borders; piped output stays unwrapped.- On Linux, replacing the
peppybinary while the daemon runs no longer strands built-in MCP nodes: the daemon serves them from its running image, warns in the add log, and adopts the new binary on restart.
v0.27.0 (Alpha): Peppy now configures pairings-hub as a fifth default repository, so shared pairing definitions resolve without any setup.
- Reference shared pairing definitions by
name:tagindepends_on.pairingsstraight away, withpairings-hub(id1004) now configured as a default repository.
v0.26.2 (Alpha): MCP tasks for feedback-less actions now settle on their result, and release artifacts no longer carry the build machine's identity.
MCP server
- MCP tasks backed by an action that declares no feedback now settle on the provider's result instead of stalling until the task deadline.
Release artifacts
- Release archives are packed with neutral ownership, so installing them as root inside a user namespace no longer fails or hands the files to a same-named local account.
- The
peppybinary and the bundled apptainer man pages no longer embed the build machine's home directory or source paths.
v0.26.0 (Alpha): Serve MCP exposures from the server built into peppy by listing them in a launcher, with no node to generate or build.
Breaking changes
-
peppy repo exposureis removed, and an exposure is no longer a committed bundle plus a generated MCP server node. Validate exposures withpeppy repo index --check --validate-mcp-exposuresand delete the old generated artifacts. -
Serve an exposure from a launcher's
source: { exposures: ["<name>:<tag>", ...] }instead of deploying its generated<name>_mcpnode; the server built intopeppybinds127.0.0.1:<port>, one endpoint per exposure at/<name>/<tag>/mcp. -
peppy mcp catalog <name:tag>prints the catalog an endpoint advertises: every resource, tool, and task with its public name, policies, and derived JSON Schemas. -
A target's contract
sha256is now optional; omit it and the exposure follows the contract as its repository evolves, with each launch pinning the bytes it resolves. -
One deployment can serve several exposures on a single port, sharing a contract slot when two exposures name the same target and the same contract.
-
peppy stack listadds anInstance endpointstable listing each endpoint URL an instance serves. -
Exposure deployments work in a federated launch: the exposure documents and the contracts they reference are pinned and shipped to the machine hosting the instance.
-
A new default
mcp-hubrepository resolves the MCP exposure documents a launcher lists. -
An exposure manifest may carry a
labelslist of free-form strings for whoever browses the repository.
v0.26.1 (Alpha): The OpenArm-specific node repository is no longer configured out of the box, leaving four default repositories whose ids shift.
Breaking changes
- The default repositories no longer include
openarm-nodes(the OpenArm01-specific nodes); to keep using those nodes, add the repository to your configuration yourself. - The built-in ids of
contracts-hubandmcp-hubare now1002and1003(previously1003and1004); update anything that references them by id.
v0.25.7 (Alpha): `stack resolve` now checks link rules without a daemon, and generated bindings decode string-list payload fields.
stack resolve
stack resolvenow checks the flat plan against the link rules it can verify without a daemon (slot keys, vacancies, and pairing coverage) and fails early when one breaks.- The resolution report ends with a line saying whether those link rules were checked, or why the check was skipped and to run
peppy repo refresh.
Message payloads
- Topic and action payloads can now include string-list fields (
$type: "array"with$items: "string"), and the generated bindings decode them.
v0.25.5 (Alpha): Pin a contract or pairing's generic arrays to your node's length with `refine`, and harden how servers decode goals.
- Pin a contract or pairing document's generic arrays to a fixed length for your node with a
refineblock on an implements, consumes, or pairing entry. - A generated action server now rejects a goal whose request bytes do not fit its declared shape with the decode error and keeps serving, never reaching your decider.
- Python nodes now raise a
ValueErrorwhen a fixed-length array is encoded or decoded with any other number of elements, matching Rust's fixed-size arrays.
v0.25.6 (Alpha): Adds a `peppy --version` flag that prints the CLI version straight from the binary, without contacting the daemon.
- Run
peppy --version(or-V) to print the CLI version alone, straight from the binary, without starting or contacting the daemon.
v0.25.2 (Alpha): The generated test harness serves the daemon clock, so you can boot nodes in sim time and drive it, or skew wall time.
- Boot a node in sim time under the generated test harness with
use_sim_timeand drive its virtual clock yourself withharness.clock.tick(...), with no time existing until you tick. - Skew the wall clock the harness serves with
harness.clock.set_offset_ns(...)to exercise a node's clock-offset handling without touching the host clock. - Run standalone (daemon-less) nodes in sim time with
StandaloneConfig.with_use_sim_time(...), which no longer requires a real daemon stack. peppygen.clock.initnow rebinds when a different node initializes it, so consecutive test-harness boots in one process each read their own clock.
v0.25.3 (Alpha): A maintenance release with internal updates only; no user-facing changes.
- No user-facing changes in this release.
v0.25.4 (Alpha): This release contains internal maintenance only, with no user-facing changes.
No user-facing changes. This release contains internal maintenance only.
v0.25.0 (Alpha): peppy generates mock and fixtures test surfaces for Rust and Python nodes, plus a Testing guide and a scaffolded harness.
Testing
- peppy now emits mock and fixtures test surfaces into the generated
peppygenpackage for both Rust and Python nodes, so you can test your nodes against generated mocks and fixtures. - Multi-instance mock slots now carry explicit instance ids, so tests can address each instance individually.
- Optional pairing slots gain a vacant-boot knob for booting a node with the optional peer left unpaired.
- Generated mocks honor the per-interface consumer link ids you declare.
peppy node initnow scaffolds a lib/main split and a harness smoke test for new nodes.- A new Testing guide covers writing tests with mocks, teardown, and the cardinality knobs.
v0.25.1 (Alpha): Spawned nodes no longer inherit the caller's PYTHONPATH and PYTHONHOME, alongside documentation fixes for node commands and launcher options.
Breaking changes
- Spawned nodes no longer inherit the caller's
PYTHONPATHandPYTHONHOMEfrom the launching environment. If a node relied on either variable being passed through, set it explicitly for that node.
Documentation
- The
peppy node runexample in the actions guide is corrected so it works as written. - The quickstart and README now document the launcher-with-options syntax.
v0.24.1 (Alpha): Launchers can now declare `constraints`, including `forbids`, that refuse incompatible selections in the composition model and explain each refusal.
Launcher constraints
- Launcher definitions accept a new
constraintsblock that turns invalid combinations into selection refusals in the composition model, rejecting incompatible choices before a launch is composed. - The
forbidsrule declares selections that cannot be combined, and refusal messages lead with the choice that triggered them so it is clear which selection to change. - Constraint diagnostics name the constraint that shadows an unreachable one and flag a bare launch that exceeds the allowed ceiling.
v0.24.0 (Alpha): Compose launchers from fragments with --with selections and a new stack resolve command, plus sturdier container builds.
Launch composition
- Peppy parses composed launchers and flattens a launcher selection into a single flat launcher.
--withselections are resolved on the coordinator, and the newstack resolvecommand reports the resolved stack.- A single launcher fragment can no longer both replace and append to the same slot; peppy rejects fragments that do.
- Launcher fragment validation covers previously missed cases, tightening composition safety.
Containers
- Container builds are retried automatically when the base image fetch fails transiently.
- Peppy checks for
fuse2fson hosts that run rootless Apptainer containers.
Networking
- Peppy supports a wildcard peer listener for peer discovery.
Output
- Peppy announces a cached-checkout reuse once per checkout population.
v0.23.3 (Alpha): Adds the mcp_exposure/v1 format for generating MCP server nodes and task bridges, and keeps slow-connection launches alive.
MCP exposure
- The new
mcp_exposure/v1format lets you declare MCP exposures, which peppy wires into the repository and publishes as exposure bundles. - An exposure generates an MCP server node together with action-backed task bridges, whose feedback QoS is derived from the contract rather than a fixed default.
Launches and containers
- Container
mount_pathsthat start with~are now expanded to the home directory on the machine that binds them. - Launches over slow connections stay alive by reporting genuine build progress instead of stalling.
Documentation
- MCP exposure is now covered by its own dedicated advanced guide.
v0.23.2 (Alpha): Absent optional node dependencies are now accepted when the slot allows an empty bound set, with clearer guides.
Dependencies
- A node dependency may now be absent when its slot admits an empty set of bounds, so optional dependencies no longer need to be present to satisfy resolution.
Documentation
- The guides now document how to add an optional dependency and correct the wording used to describe the dependency walk.
- The guides now name the both-sources failure and describe the add-path cache fallback.
- The guides now accurately describe worklist deduplication and launch vacancy.
v0.23.1 (Alpha): Observer seeding now covers peer-placed observers, and generated code gains typed accessors for observed pairings.
Observers
- Observer membership is stamped into the boot config when an observer spawns, so observers are seeded correctly, including observers placed on peers.
- The observation seed spawn path is fixed so observations seed reliably.
Generated code
- Generated Rust and Python code now exposes cardinality-typed
source()andsources()accessors for observed pairings.
Documentation
- The pairing and standalone node documentation now reference the
--linkflag.
v0.23.0 (Alpha): This release contains no user-facing changes.
No user-facing changes in this release.
v0.22.1 (Alpha): Generated pairing subscriptions now tag each message with the subscribing slot's identity.
Pairing
- Generated pairing subscriptions now tag every message with the subscribing slot's identity, so paired nodes can tell which slot a message came from.
v0.22.0 (Alpha): Slots gain cardinality-based sizing, links can be left vacant, and refreshes report unreadable repositories instead of failing.
Breaking changes
defer_linksis replaced by a vacant link value. Replace anydefer_linksentry in your links maps with the vacant link value.- Participant slots no longer accept the
optionalfield. Express whether a participant slot may be left unfilled through its cardinality instead.
Slots and links
- Producer slots now bind at most one producer.
- Observer slots are sized by their cardinality.
- A link may be left vacant only when the node manifest declares itself optional.
Repository refresh
- A refresh now reports the repositories it could not read and continues instead of failing the entire run.
v0.21.0 (Alpha): Federated launches span machines, repositories resolve through a committed index, and launchers pin registry sources.
Breaking changes
- Repository entries now resolve through a committed repository index rather than being resolved ad hoc, and every cache entry is pinned to a git commit; generate and commit the index with the new
peppy repo indexcommand, whose--checkmode verifies the committed index is up to date. - Launcher deployment sources are restricted to
name:tagregistry references that resolve to node pins, and retired source keys are refused with a migration message, so update your launcher files to reference nodes by registryname:tag.
Federation
- A federated launch now spans multiple machines through cross-machine dispatch.
- The launcher places and preflights federated core node links across machines.
peppy resetrediscovers federated reset targets from the federation instead of from local memory.- Cross-daemon pairing peers are stamped with their own core node in display reads.
- Filesystem-backed repositories cannot participate in federation.
Pairing and dependencies
depends_ongains a fourth peer-coupling level,pairing_observers, across the daemon and launcher.- The surviving instance of a pair still receives the dissolution notice after its partner has already stopped.
Launcher and launch
- Launcher files accept per-instance
env_vars. - The launch summary lists every machine's node log files.
- A coordinator's next launch takes over its own stale reservation through a lease instead of being blocked by it.
- The caller's environment stays on the caller's machine, so peer builds no longer inherit it.
Containers
- Each peer prepares its own container bind mounts, and relative container mount sources are forwarded to Lima as absolute paths.
- Restarts that would kill running containers are refused, and container bind sources are prepared before a participant slice takeover.
- Apptainer SIF images are FUSE-mounted instead of extracted, with squashfuse bundled alongside apptainer.
Repositories
peppy repo refreshcaches its checkout for reuse, prunes orphaned checkouts, applies filesystem exclusions before reading declared items, and skips re-pushing stack entries whose manifest is unchanged.- Repository resolution failures are reported and contained instead of guessed, with clearer failure reports.
Messaging and code generation
- The Rust and Python generators handle
$optionalscalars and payload-less feedback topics consistently.
Documentation
- The documentation is aligned with the current commands, outputs, and behavior.
- Federation coordination guidance and the producer-link example are clarified, with the example showing separate per-node manifests.
v0.20.0 (Alpha): Adds `peppy platform list` to view your workspace's core nodes and makes `peppy platform logout` deregister this machine's node.
Platform
- The new
peppy platform listcommand shows your workspace's core nodes and their status, reporting both the application layer and the network layer for each node. peppy platform logoutnow deregisters this machine's core node when you log out.
Documentation
- The quickstart page now includes a quickstart video.
- The README has been rewritten with installation instructions, CLI usage, and links to the documentation.
v0.19.1 (Alpha): Peppy tightens how container nodes handle host and temp paths, and adds a Quickstart from install to a simulated arm.
Breaking changes
- Container nodes no longer inherit the caller's temporary directory. If a container node relied on that path, provide it explicitly.
- Peppy no longer auto-creates bind mount source paths that the host is expected to provide. Create those directories before starting the node, or the mount will fail.
Container and host-runtime behavior
- When a host runtime path is not available inside the VM, peppy now reports the actual constraint instead of a less specific error.
- Closed a case where a run command could bypass the restrictions on host runtime paths.
Documentation
- Added a Quickstart that walks you from installing peppy to a simulated OpenArm in three steps.
v0.19.0 (Alpha): Actions adopt the goal-ack envelope and split goal/result endpoints; the generator now honors declared goal response schemas.
Breaking changes
- Actions now use the framework goal-ack envelope for goal acknowledgements; update any consumer that parses goal acknowledgement messages to the new envelope format.
- Action endpoints are now split into separate goal and result endpoint types; update any configuration or code that referenced the previous combined action endpoint type.
- Generated goal responses no longer include an error field; update any code that read that field.
Code generation
- The code generator now honors the goal response schemas you declare, so generated goal responses match your declaration; regenerate to pick up the change.
Documentation
- The guide pages have been revised to fix inconsistencies and formatting issues.
v0.18.0 (Alpha): Adds observer slots, unifies binding and pairing into links, reworks zenoh config, and spans stack list across daemons.
Breaking changes
- The
peppy authcommand group is renamed topeppy platform; update any commands or scripts that callpeppy auth. - The
--bindand--pairflags are replaced by a single--linkflag; switch your commands to use--link. - Launch files now use unified
linksanddefer_linksfields in place of the previous separate binding and pairing entries; migrate your launch files to the new fields. - Zenoh settings in
peppy_config.json5are restructured into azenohsection with taggedzenoh.managedandzenoh.externalblocks, replacing the flatzenoh,zenohd, andpeerfields, and unknown fields underzenohare now rejected; move your settings into the new blocks. The newzenoh.externalblock lets peppy run against an operator-managed zenoh router. peppy stack listno longer prints DOT graph output; it now always renders a report of per-core-node sections aggregated across every live daemon, including live instance counts and the answering daemon's identity, so update anything that parsed the old graph output.- Generated peppygen modules for slots are now nested at
<category>/<link_id>/<member>; update the import paths for your generated code. - The
PEPPY_DAEMON_STATE_FILEenvironment override is removed; the daemon state file now lives under$PEPPY_HOME, so stop settingPEPPY_DAEMON_STATE_FILE. - The "organization"/"org-id" concept is renamed to "workspace"/"namespace" across authentication and daemon output; update references and scripts that use the old terms.
Observers
- Nodes can now declare observer slots to observe topics, with generated observer bindings (including an
ObservedSourcetype) and delivery of observers to running nodes. - Guides and launch-file documentation now cover observer slots and the
links/defer_linksmodel.
Multi-daemon and federation
- Daemons can participate in a federated peer topology across zenoh routers.
- Federation-aware CLI commands now surface listener and serve errors instead of hanging.
Other changes
- Removing a node with
node remove --stop-instancesnow also dissolves that node's links. - A new
PEPPY_CONFIGenvironment variable overrides the daemon config file path. - Only one peppy daemon can run per
$PEPPY_HOMEdata root, enforced by an exclusive singleton lock. - Config drift now logs which
peppy_config.json5settings it adds when completing missing defaults. - Newly generated core-node default names use the compact
cn-{adj}-{surname}format instead of the longercore-node-{adj}-{surname}-{4digits}-{10digits}form. - The bundled Cap'n Proto compiler is now installed under
$PEPPY_HOME/bin, and its location is documented.
Documentation
- External federation guidance adds a dedicated section on namespace handling outside the Peppy platform.
v0.17.0 (Alpha): Dependency slots gain explicit cardinality, letting a slot bind to multiple producers through a uniform consumer API.
Dependency-slot cardinality
- Dependency slots now support explicit cardinality, letting a slot bind to one or more producers instead of exactly one.
- Bindings can target multiple producers, and consumers read them through a uniform
bound_producers()API regardless of cardinality. - Generated producer accessors reflect each slot's cardinality: single-producer slots expose
bound_producer()while multi-producer slots exposebound_producers(). - Bindings can now specify explicit service and action targets.
- Slots declared
one_or_moremust be non-empty, and this check now applies to programmatically suppliedFlagsvalues as well as arrays.
v0.16.0 (Alpha): Renames interfaces to contracts, tightens `depends_on` slot validation, and fixes macOS container builds.
Breaking changes
- The
conforms_tomanifest field has been renamed toimplementsas part of a broader rename of "interfaces" to "contracts"; renameconforms_totoimplementsin yourpeppy.json5and update any "interface" wording to "contract". - Dependency slots (
depends_on) now require a single producer each, replacing the previousfrom_anybinding model, and peppy now fails validation whenever adepends_onslot is left unfulfilled; update your bindings so every slot names exactly one producer.
Container builds and runs (macOS)
- macOS container builds no longer silently default to
$HOMEand now use the current working directory. - The peppy data root is now mounted into the Lima VM so container builds and runs can access it.
- Fixed a hang where restarting the Lima VM blocked the async runtime while registering a host mount for the first time.
- Container Python bindings no longer ship stale native extensions after shared-crate changes.
Validation and output
- Contract (
implements) validation failures now report per-slot coverage mismatches instead of a single combined string. - The CLI info output formatting has been simplified.
Documentation
- The advanced guides now include Python examples alongside the existing Rust examples.
- The Python async examples now wrap
select!in a loop and hold references to asyncio tasks so they are not cleaned up or garbage-collected prematurely.
v0.15.1 (Alpha): Adds remote core node targeting and collision detection, renames the serve command and the shared-directory variable.
Breaking changes
- The
PEPPYOS_SHARED_DIRenvironment variable has been renamed toPEPPY_SHARED_DIR; update your environment so the shared directory stays configured.
Core node targeting
- The
--core-nodeflag can now target a remote core node and is accepted bynode add,node sync, andrepo add. - The
--core-nodeflag is now validated as the command is parsed, so invalid values are reported immediately. - peppy now detects core node name collisions.
Serve reliability
peppy service servenow shuts down cleanly when an error occurs during startup.
v0.15.0 (Alpha): Nodes can now declare, establish, and dissolve pairings with one another, and serve restarts and shutdowns are more reliable.
Node pairing
- Nodes can now declare, establish, and dissolve pairings (peer links) with one another at runtime.
- Each paired node exposes a
LINK_IDand apairingsview in its generated module so node code can identify and work with its active links. peppy stack listnow shows an "Instance pairings" section listing the active pairings between running instances.- Malformed pairing targets are now rejected, and pairing delivery is protected against a link being dissolved concurrently.
Serve reliability
peppy serveno longer drops shutdown signals or races when restarting, so restarts and shutdowns now behave reliably.
v0.14.0 (Alpha): Logging in now connects your daemon to a per-user TLS-verified cloud router, and topics move to a new Subscription API.
Breaking changes
- Topic subscriptions no longer use the per-call
on_next_message_receivedmethod; subscribing now returns aSubscriptionthat you hold and read messages from, so update your node code to use it.
Authentication and cloud routers
- Logging in now fetches and caches your per-user cloud (zenoh) router configuration and federates your daemon to it live.
- peppy verifies the router's TLS certificate when you log in.
- Logging in or out now takes effect immediately, regenerating and restarting the daemon and propagating your organization namespace through it.
- Fixed a cross-identity organization cache leak, added a daemon restart when the namespace drifts at startup, and hardened login and logout edge cases.
- The restart warning is now skipped when your daemon stack has no user nodes.
Releasing
- Added a
--skip-prod-cert-checkflag to bypass the production-router certificate gate when running a release.
Topics
- Tightened how subscriptions behave once they are closed, across generated node code and the docs.
Reliability
- peppy now retries transient
ETXTBSYandENOENTexec errors when extracting the ruff binary during parallel binary extraction.
Documentation
- Clarified that
reconnect_after_secsandrepull_afterare cache-freshness hints rather than keepalive deadlines.
v0.14.1 (Alpha): Bundle downloads retry transient failures, AppArmor profiles are per-install, and node run drops the legacy --link-id flag.
Breaking changes
- The legacy
--link-idflag has been removed fromnode run; remove it from any commands or scripts that still pass it.
Node downloads and runtime
- Transient HTTP failures when downloading node bundles are now retried automatically with bounded backoff, making node setup more resilient to flaky networks.
- Empty environment variable path overrides are now treated as unset, so an empty value falls back to the default instead of being used as a literal path.
AppArmor
- AppArmor profiles are now namespaced per Apptainer installation path, so multiple Apptainer installations no longer collide.
- The AppArmor fix script now shell-escapes the starter path correctly, so installation paths containing special characters work.
v0.13.0 (Alpha): Adds OAuth device-flow sign-in through the new peppy auth commands and moves schema identifiers to a slash-separated form.
Breaking changes
- Schema identifiers now use a slash separator (
node/v1,interface/v1,launcher/v1); update the schema references in yourpeppy.json5to the new slash-separated form.
Authentication
- Added
peppy auth login,peppy auth logout, andpeppy auth whoamito sign in, sign out, and check your current identity using the OAuth device flow.
v0.12.1 (Alpha): Adds signal handling and bind-mount safety.
Container lifecycle
- Lima liveness checks now share a bounded wait helper and enforce per-probe timeouts.
- Native containers now fall back to a host SIGTERM when the in-guest signal is unavailable.
- In-VM container processes on macOS now receive a cooperative SIGTERM phase before being force-killed.
Stack
- All container bind mounts are now pre-flighted before any instance is started.
v0.12.0 (Alpha): Remove emit topics API that could cause deadlocks on large payloads
What's Changed
Full Changelog: v0.11.1...v0.12.0
v0.11.1 (Alpha): Fix a bunch of deadlocks on node stop
What's Changed
- Optimize config-internal by @godardt in #252
- Optimize core-node-api by @godardt in #253
- Optimize core-node-internal by @godardt in #254
- Optimize generator-internal by @godardt in #255
- Optimize containers-internal by @godardt in #256
- Optimize latency-report by @godardt in #257
- Optimize the peppy crate by @godardt in #259
- Optimize node-stack-internal by @godardt in #258
- refactor(pmi): harden public API, purify session-config builder, forbid unsafe by @godardt in #260
- Refactor peppylib and peppylib-py by @godardt in #261
- Fix stop clock and heartbeat publishers before closing the messaging session by @godardt in #262
- Fix nodes termination unhealthy when nodes are tasks that exit by @godardt in #263
- Release v0.11.1 by @godardt in #264
Full Changelog: v0.11.0...v0.11.1
v0.11.0 (Alpha): Add many fixes to the public APIs, especially with actions
What's Changed
- Deploy peppylib as a standalone installable project in Python nodes by @godardt in #240
- Fix producer death block by @godardt in #242
- Add on_shutdown hook phase with grace-bounded LIFO execution across all node stop paths by @godardt in #243
- Add
stack benchmarkimprovements by @godardt in #244 - fix: Replace half-address producer refs with fully-qualified ProducerRef by @godardt in #246
- Fix force node stop on
node buildby @godardt in #245 - Fix
node stoptargeting wildcard core nodes by @godardt in #247 - fix: isolate peppy data root per CI run to prevent cross-run collisions by @godardt in #249
- Return full producer identity (core_node + instance_id) from consumed topic callbacks by @godardt in #248
- docs: sync with PR #250 by @godardt in #251
- Release v0.11.0 by @godardt in #250
Full Changelog: v0.10.5...v0.11.0
v0.10.5 (Alpha): Fix `node stop` and daemon kill graceful shutdowns
What's Changed
- Switch to Zenoh peer sessions for direct peer-to-peer data paths by @godardt in #236
- docs: sync with PR #234 by @godardt in #235
- Fix zombie processes of nodes in the node stack by @godardt in #237
- Refactor build helpers by @godardt in #238
- Release v0.10.5 by @godardt in #239
Full Changelog: v0.10.4...v0.10.5
v0.10.3 (Alpha): Add support for shared datastore
What's Changed
- Remove deferred binding support by @godardt in #229
- Add from_any bidirectional guide with robot arm snippets by @godardt in #230
- Add memory store by @godardt in #228
- Extract router feature flag and split zenohd submodules by @godardt in #232
- Release v0.10.3 by @godardt in #231
Full Changelog: v0.10.2...v0.10.3
v0.10.2 (Alpha): Fix bidirectional communication design
What's Changed
- docs: sync with PR #221 by @godardt in #222
- Remove external consumed topics, all consumed topics now require a link_id by @godardt in #223
- Rework bidirectional comm by @godardt in #224
- Add bidirectional communication via interfaces by @godardt in #225
- Release v0.10.2 by @godardt in #226
Full Changelog: v0.10.1...v0.10.2
v0.10.1 (Alpha): Fix stack list display as well as --force flag on node build
What's Changed
- fix: release gate slot before completing goal to eliminate "action already in progress" race by @godardt in #217
- Fix zenohd stdout/stderr to file to prevent pipe buffer deadlock by @godardt in #218
- Improve the output of the
stack listcommand by @godardt in #219 - Fix zombie processes by @godardt in #220
- Release v0.10.1 by @godardt in #221
Full Changelog: v0.10.0...v0.10.1
v0.10.0 (Alpha): Add interface conformance along with fixes to action
What's Changed
- Improve install script by @godardt in #192
- Variants removal by @godardt in #191
- Release v0.9.3 by @godardt in #196
- Interfaces conformances 1 by @godardt in #197
- Interfaces conformances: standard structures by @godardt in #198
- Replace semver tags with non-dotted tags by @godardt in #199
- Refactor pmi-internal by @godardt in #201
- Implement the
conforms_tobusiness logic for interface conformance by @godardt in #200 - Fix interfaces & nodes on the wire by @godardt in #202
- Add depends.on.interfaces business logic by @godardt in #203
- Add launcher bindings business logic by @godardt in #204
- Throw warnings on missing
link_idduringpeppy runby @godardt in #205 - Fix launcher and
node runbindings by @godardt in #206 - Add instance_ids fetch by node name + node tag by @godardt in #207
- docs: sync with PR #209 by @godardt in #210
- Fix action communication by goal ID by @godardt in #214
- Replace raw cancel/result payloads with typed ResultStatus and CancelState by @godardt in #215
- Revision release v0.10.0 by @godardt in #211
- Release v0.10.0 by @godardt in #216
Full Changelog: v0.9.3...v0.10.0
v0.9.3 (Alpha): Fix peppy actions misalignment
What's Changed
- feat: bundle gocryptfs alongside apptainer for encrypted overlay support by @godardt in #193
- Fix action communication misalignment by @godardt in #195
Full Changelog: v0.9.2...v0.9.3
v0.9.2 (Alpha): Add documentation for actions with optional fields
What's Changed
Full Changelog: v0.9.1...v0.9.2
v0.9.1 (Alpha): Fix cancel token during action feedback when the action ends
What's Changed
- docs: sync with PR #184 by @godardt in #185
- Fix Action feedback deadlock by @godardt in #187
- Release v0.9.1 by @godardt in #188
Full Changelog: v0.9.0...v0.9.1
v0.9.0 (Alpha): Add support for launchers repositories
Main changes
schema_versionis nowpeppy_schema: "node_v1"orpeppy_schema: "launcher_v1"depending if it's a node or a launcherpeppy stack launch <launcher_filename>now works with remote launchers. The https://github.com/Peppy-bot/launchers_hub repository is added by default. Runningpeppy stack launch ./<launcher_filename>defaults to a local path, whilepeppy stack launch <launcher_filename>defaults to a launcher in the repositories
What's Changed
Full Changelog: v0.8.5...v0.9.0
v0.8.5 (Alpha): Add ability to use `peppy node sync -r` to use repositories
What's Changed
- Add
node sync -rto synchronize with repositories by @godardt in #181 - Release v0.8.5 by @godardt in #182
Full Changelog: v0.8.4...v0.8.5
v0.8.3 (Alpha): Add wall & sim clock support
What's Changed
- Feature clock sync by @godardt in #176
- Add sim-clock mode with per-instance framework overrides by @godardt in #177
- Release v0.8.3 by @godardt in #178
Full Changelog: v0.8.2...v0.8.3
v0.8.2 (Alpha): Add core node information available to peppylib
What's Changed
- Extract capnp encoding types into new core-node-api crate by @godardt in #172
- Peppylib stack list command implementation by @godardt in #173
- docs: sync with PR #174 by @godardt in #175
- Release v0.8.2 by @godardt in #174
Full Changelog: v0.8.1...v0.8.2
v0.8.0 (Alpha): Add support for repositories
What's Changed
✨ Highlight: Repositories. This release introduces first-class repositories, a new way to tell peppy where to discover nodes. Register local directories, git repositories (with optional branch/tag pinning via --ref), or HTTP endpoints with peppy repo add, then run peppy repo refresh to build a cached index of every available node. Once indexed, nodes can be added by their short name:tag form (e.g. peppy node add uvc_camera:0.1.0) and launched in the node stack without pointing at a path or URL.
- Add repositories feature by @godardt in #161
- Automatically test for docs drift by @godardt in #163
node addcommand now works with node name + tag from repositories by @godardt in #162- Add ability to use
stack launchwith nodes from repositories by @godardt in #164 - docs: sync with PR #165 by @godardt in #166
- docs: sync with PR #165 by @godardt in #167
- docs: sync with PR #165 by @godardt in #168
- Release v0.8.0 by @godardt in #165
Full Changelog: v0.7.0...v0.8.0
v0.7.0 (Alpha): Separate `node add/start` into `node add/build/run`
What's Changed
- Add
node buildstep to workflow by @godardt in #153 - Separate
node addfromnode buildcommands by @godardt in #155 - refactor: rename
start_cmdtorun_cmdby @godardt in #156 - Fix standalone integration by @godardt in #157
- Change
node infoto look up nodes by name:tag by @godardt in #158 - Add
nodecommand shorthands by @godardt in #159 - Release v0.7.0 by @godardt in #160
Full Changelog: v0.6.2...v0.7.0
v0.6.2 (Alpha): Add code and command optimizations
What's Changed
- Code cleanup & optimization by @godardt in #149
- Node sync path by @godardt in #150
- Core node name is now fixed across reboot/reinstallation by @godardt in #151
- Release v0.6.2 by @godardt in #152
Full Changelog: v0.6.1...v0.6.2
v0.6.1 (Alpha): Add support for arrays of objects in message format schemas
What's Changed
- Support arrays of objects in message format schemas by @godardt in #147
- Release v0.6.1 by @godardt in #148
Full Changelog: v0.6.0...v0.6.1
v0.6.0 (Alpha): Add support for node variants
What's Changed
- Create a dedicated
runtimesection to holdlanguage,container,parametersandadd_cmd/start_cmdby @godardt in #136 - Node variants by @godardt in #137
- Docker base images by @godardt in #143
- Fix variants by @godardt in #142
- Add more meaningful output to the
node addoperation by @godardt in #144 - Add variant launchers support by @godardt in #145
- Release v0.6.0 by @godardt in #146
Full Changelog: v0.5.10...v0.6.0
v0.5.10 (Alpha): Add support for installation in containers
What's Changed
Full Changelog: v0.5.9...v0.5.10
v0.5.8 (Alpha): Fix architecture mismatch in Apptainer binary
What's Changed
Full Changelog: v0.5.7...v0.5.8
v0.5.7 (Alpha): Official support for more Linux distros
What's Changed
Full Changelog: v0.5.6...v0.5.7
v0.5.6 (Alpha): Add support for mounted devices in containers
What's Changed
- refactor: simplify PR 128 by @claude[bot] in #131
- Add extra args support for apptainer build/run and lima shell by @godardt in #128
- Add documentation for llms by @godardt in #132
- v0.5.6 by @godardt in #133
Full Changelog: v0.5.5...v0.5.6
v0.5.5 (Alpha): Fix issues with installation script on some systems
What's Changed
- Improve install scripts by @godardt in #126
- Containers mounts with runtime vars by @godardt in #125
- fix: switch container images to standard registries by @godardt in #129
- v0.5.5 by @godardt in #130
Full Changelog: v0.5.4...v0.5.5
v0.5.0 (Alpha): Bidirectional communication support
What's Changed
- Rework peppy structure by @godardt in #102
- Separate DAG from communication by @godardt in #104
- Fix/actions revamp by @godardt in #106
- Add bidirectional communication by @godardt in #107
- Fix node add with existing instances by @godardt in #109
- Improvement launch files by @godardt in #112
- Fix yanked file by @godardt in #114
- Optimize modules by @godardt in #113
- Release 0.5.0 by @godardt in #115
Full Changelog: v0.4.0...v0.5.0
v0.5.1 (Alpha): Add more explanatory logs for add_cmd and start_cmd failures
What's Changed
- Include command name in spawn and execution failure error messages by @godardt in #116
- Add more explanatory logs for add_cmd and start_cmd failures by @godardt in #117
Full Changelog: v0.5.0...v0.5.1
v0.5.3 (Alpha): Fix Linux .so Python lib not available for x86_64 systems
What's Changed
- Fix Linux .so Python lib not available for x86_64 systems by @godardt in #121
- Release v0.5.3 by @godardt in #122
Full Changelog: v0.5.2...v0.5.3
v0.5.4 (Alpha): Add various fixes to the install script
What's Changed
- Various fixes to the install script by @godardt in #123
- Add various fixes to the install script by @godardt in #124
Full Changelog: v0.5.3...v0.5.4
v0.4.0 (Alpha): Containers support
What's Changed
- Feature/fix cross compilation by @godardt in #90
- Add fakeroot pre-flight check and service stop/uninstall commands by @godardt in #91
- Final implementation for containers by @godardt in #88
- fix: auto-create host-side bind mount source directories by @godardt in #92
- Replace fixed timeouts with idle + max timeout model for node by @godardt in #93
- Fix python libs by @godardt in #95
- Optimize codegen by @godardt in #96
- Fix containers warnings by @godardt in #97
- fix: move DEBIAN_FRONTEND export to %post section in apptainer templates by @godardt in #98
- rename: daemon-node crate and related identifiers renamed to core-node by @godardt in #99
- Add Lima VM cross-compilation for multi-target releases by @godardt in #100
- Release v0.4.0 by @godardt in #101
Full Changelog: https://github.com/Peppy-bot/peppy/commits/v0.4.0
v0.3.6 (Alpha): Optimize PeppyOS internal behavior
- sccache support
- Optimize
node addcommand - Update Python node template to use direct venv execution
- Add external JSON parameter loading for standalone nodes in Python and Rust
v0.3.5 (Alpha): Trim Rust nodes size
v0.3.4 (Alpha): Optimize crates boundary crossing with Rust nodes
v0.3.0 (Alpha): Python support
- Add python support
- Rust codegen refactor
- Rename master-node to daemon-node
- Remove extra deps in nodes
v0.3.1 (Alpha): Add Python support with macOS (aarch64) and Linux (x86_64/aarch64) support
- Add python support
- Rust codegen refactor
- Rename master-node to daemon-node
- Remove extra deps in nodes
v0.3.2 (Alpha): Fix missing binaries for Python
v0.3.3 (Alpha): Support dataclass instances in with_parameters method in Python
v0.2.17 (Alpha): Fix for names-generator
v0.2.18 (Alpha): Update all dependencies
v0.2.15 (Alpha): Add interfaces integrity
v0.2.13 (Alpha): Add dependency check to add command
v0.2.14 (Alpha): Add user defined timeouts to add/start and launch cmd
v0.2.12 (Alpha): Fix add_cmd and start_cmd user vars
Fixed user variables not being properly applied in add_cmd and start_cmd operations.
v0.2.11 (Alpha): Update docs & add optimizations
Implement internal code optimizations
v0.2.10 (Alpha): Initial alpha release of PeppyOS
Features
- Core node system with Rust support
- Topic-based communication between nodes
- Service and action patterns
- Parameter system for node configuration
- Launch files for multi-node orchestration
- Node stack management
- Standalone node execution mode
- CLI tools for project management