Skip to content

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_participants with use_sim_time in 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/config selects for each host through ssh -G, honoring your Host, Match, Include, IdentityAgent, and IdentityFile settings.
  • The daemon binds the agent your IdentityAgent names once at startup and logs which one, making 1Password, Secretive, and gpg-agent reachable even from a service installed with peppy 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/config is 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 build reuses a stored artifact when the staged sources are byte-identical to an earlier build's, skipping build_cmd or apptainer build and logging Reusing 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 launch reuses cached builds for every deployment, on the coordinator and on every peer, so relaunching the same launcher skips rebuilding unchanged nodes.

  • Pass --rebuild to peppy node build or peppy stack launch to 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, and git entries in repositories.json5 an SSH URL (git@host:owner/repo.git or ssh://) to reach a private repository, authenticating through your ssh-agent and ~/.ssh keys the way ssh does.
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 the tick.time field; Python keeps the .time attribute.

  • Reading simulated time now requires a daemon that serves it, so an instance with use_sim_time: true is 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 its SimTimePublisher every 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 --json output of peppy repo show now carries a pairing_slots array in each report, each entry giving the slot's link_id, pairing, role, optional, and the peers that 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 to peppy stack launch or stack resolve now resolves through the repository cache only, never a same-named file in the current directory; write ./name.json5 to launch a local file.
  • Run peppy repo refresh after 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 search and repo show accept --json for machine-readable output and read the local caches, so they need no daemon.

Other improvements

  • peppy stack list --json prints the discovered core nodes and their stacks as one JSON document.
  • stack list panels and the repo search / repo show tables now fit the terminal, wrapping over-long cells inside the borders; piped output stays unwrapped.
  • On Linux, replacing the peppy binary 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:tag in depends_on.pairings straight away, with pairings-hub (id 1004) 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 peppy binary 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 exposure is removed, and an exposure is no longer a committed bundle plus a generated MCP server node. Validate exposures with peppy repo index --check --validate-mcp-exposures and delete the old generated artifacts.

  • Serve an exposure from a launcher's source: { exposures: ["<name>:<tag>", ...] } instead of deploying its generated <name>_mcp node; the server built into peppy binds 127.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 sha256 is 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 list adds an Instance endpoints table 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-hub repository resolves the MCP exposure documents a launcher lists.

  • An exposure manifest may carry a labels list 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-hub and mcp-hub are now 1002 and 1003 (previously 1003 and 1004); 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 resolve now 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 refine block 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 ValueError when 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_time and drive its virtual clock yourself with harness.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.init now 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 peppygen package 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 init now 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 PYTHONPATH and PYTHONHOME from the launching environment. If a node relied on either variable being passed through, set it explicitly for that node.

Documentation

  • The peppy node run example 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 constraints block that turns invalid combinations into selection refusals in the composition model, rejecting incompatible choices before a launch is composed.
  • The forbids rule 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.
  • --with selections are resolved on the coordinator, and the new stack resolve command 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 fuse2fs on 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/v1 format 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_paths that 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() and sources() accessors for observed pairings.

Documentation

  • The pairing and standalone node documentation now reference the --link flag.
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_links is replaced by a vacant link value. Replace any defer_links entry in your links maps with the vacant link value.
  • Participant slots no longer accept the optional field. 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 index command, whose --check mode verifies the committed index is up to date.
  • Launcher deployment sources are restricted to name:tag registry 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 registry name: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 reset rediscovers 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_on gains 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 refresh caches 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 $optional scalars 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 list command shows your workspace's core nodes and their status, reporting both the application layer and the network layer for each node.
  • peppy platform logout now 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 auth command group is renamed to peppy platform; update any commands or scripts that call peppy auth.
  • The --bind and --pair flags are replaced by a single --link flag; switch your commands to use --link.
  • Launch files now use unified links and defer_links fields in place of the previous separate binding and pairing entries; migrate your launch files to the new fields.
  • Zenoh settings in peppy_config.json5 are restructured into a zenoh section with tagged zenoh.managed and zenoh.external blocks, replacing the flat zenoh, zenohd, and peer fields, and unknown fields under zenoh are now rejected; move your settings into the new blocks. The new zenoh.external block lets peppy run against an operator-managed zenoh router.
  • peppy stack list no 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_FILE environment override is removed; the daemon state file now lives under $PEPPY_HOME, so stop setting PEPPY_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 ObservedSource type) and delivery of observers to running nodes.
  • Guides and launch-file documentation now cover observer slots and the links/defer_links model.

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-instances now also dissolves that node's links.
  • A new PEPPY_CONFIG environment variable overrides the daemon config file path.
  • Only one peppy daemon can run per $PEPPY_HOME data root, enforced by an exclusive singleton lock.
  • Config drift now logs which peppy_config.json5 settings it adds when completing missing defaults.
  • Newly generated core-node default names use the compact cn-{adj}-{surname} format instead of the longer core-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 expose bound_producers().
  • Bindings can now specify explicit service and action targets.
  • Slots declared one_or_more must be non-empty, and this check now applies to programmatically supplied Flags values 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_to manifest field has been renamed to implements as part of a broader rename of "interfaces" to "contracts"; rename conforms_to to implements in your peppy.json5 and update any "interface" wording to "contract".
  • Dependency slots (depends_on) now require a single producer each, replacing the previous from_any binding model, and peppy now fails validation whenever a depends_on slot 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 $HOME and 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_DIR environment variable has been renamed to PEPPY_SHARED_DIR; update your environment so the shared directory stays configured.

Core node targeting

  • The --core-node flag can now target a remote core node and is accepted by node add, node sync, and repo add.
  • The --core-node flag 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 serve now 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_ID and a pairings view in its generated module so node code can identify and work with its active links.
  • peppy stack list now 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 serve no 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_received method; subscribing now returns a Subscription that 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-check flag 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 ETXTBSY and ENOENT exec errors when extracting the ruff binary during parallel binary extraction.

Documentation

  • Clarified that reconnect_after_secs and repull_after are 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-id flag has been removed from node 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 your peppy.json5 to the new slash-separated form.

Authentication

  • Added peppy auth login, peppy auth logout, and peppy auth whoami to 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

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 benchmark improvements by @godardt in #244
  • fix: Replace half-address producer refs with fully-qualified ProducerRef by @godardt in #246
  • Fix force node stop on node build by @godardt in #245
  • Fix node stop targeting 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

Full Changelog: v0.10.4...v0.10.5

v0.10.4 (Alpha): Add `peppy stack benchmark`

What's Changed

Full Changelog: v0.10.3...v0.10.4

v0.10.3 (Alpha): Add support for shared datastore

What's Changed

Full Changelog: v0.10.2...v0.10.3

v0.10.2 (Alpha): Fix bidirectional communication design

What's Changed

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 list command 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

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

Full Changelog: v0.9.0...v0.9.1

v0.9.0 (Alpha): Add support for launchers repositories

Main changes

  • schema_version is now peppy_schema: "node_v1" or peppy_schema: "launcher_v1" depending if it's a node or a launcher
  • peppy stack launch <launcher_filename> now works with remote launchers. The https://github.com/Peppy-bot/launchers_hub repository is added by default. Running peppy stack launch ./<launcher_filename> defaults to a local path, while peppy 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

Full Changelog: v0.8.4...v0.8.5

v0.8.4 (Alpha): Add support for default parameters

What's Changed

Full Changelog: v0.8.3...v0.8.4

v0.8.3 (Alpha): Add wall & sim clock support

What's Changed

Full Changelog: v0.8.2...v0.8.3

v0.8.2 (Alpha): Add core node information available to peppylib

What's Changed

Full Changelog: v0.8.1...v0.8.2

v0.8.1 (Alpha): Fix timeouts for `stack launch`

What's Changed

Full Changelog: v0.8.0...v0.8.1

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.

Full Changelog: v0.7.0...v0.8.0

v0.7.0 (Alpha): Separate `node add/start` into `node add/build/run`

What's Changed

Full Changelog: v0.6.2...v0.7.0

v0.6.2 (Alpha): Add code and command optimizations

What's Changed

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

Full Changelog: v0.6.0...v0.6.1

v0.6.0 (Alpha): Add support for node variants

What's Changed

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.9 (Alpha): Remove Apptainer setuid

What's Changed

Full Changelog: v0.5.8...v0.5.9

v0.5.8 (Alpha): Fix architecture mismatch in Apptainer binary

What's Changed

  • Fix compilation of dependencies for correct architectures by @godardt in #138

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

Full Changelog: v0.5.5...v0.5.6

v0.5.5 (Alpha): Fix issues with installation script on some systems

What's Changed

Full Changelog: v0.5.4...v0.5.5

v0.5.0 (Alpha): Bidirectional communication support

What's Changed

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.2 (Alpha): Fix daemon installation in Linux

What's Changed

Full Changelog: v0.5.1...v0.5.2

v0.5.3 (Alpha): Fix Linux .so Python lib not available for x86_64 systems

What's Changed

Full Changelog: v0.5.2...v0.5.3

v0.5.4 (Alpha): Add various fixes to the install script

What's Changed

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 add command
  • 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