Skip to content

Changelog

All notable changes to Peppy will be documented on this page.

Subscribe to the Atom feed for updates.

v0.31.10 (Alpha): Export the daemon's log files to an OpenTelemetry endpoint, and keep credentials out of the source URLs it logs.
  • Set otlp_endpoint in the daemon configuration to export the launch, add, build, run and stack logs to an OpenTelemetry collector or intake over OTLP/HTTP, and otlp_min_severity to limit the severity sent.
  • Put export request headers, such as an API key, in the new ~/.peppy/conf/otlp_headers.json5 file.
  • Git and HTTP source URLs that the daemon writes to log lines and error messages no longer carry their credentials.
  • The "node not found" error now points at peppy stack list and peppy node add <dir> instead of a command that does not exist.
v0.31.9 (Alpha): When a pinned reference misses but the same name:tag is cached at other bytes, peppy now names each cached copy to help you fix the pin.
  • When a pinned reference misses while that name:tag is cached at other bytes, node add and node sync now name each cached copy and its source to help you fix the pin.
v0.31.8 (Alpha): Python builds can use a PyPI mirror and cache what uv downloads, and slow crate downloads no longer trip the build idle timeout.

Container builds

  • Set pypi_mirror in peppy_config.json5 to a mirror's packages base URL to download the PyPI files a Python build's uv.lock pins from that mirror instead of PyPI.
  • Python container builds on the peppy base image now cache the packages and interpreters uv downloads, so a rebuild fetches neither again.
  • Container builds expose a PEPPY_DOWNLOAD_CACHE directory a def can use to cache files it downloads, keyed by their sha256.
  • Builds run cargo with progress always on, so a slow crate download keeps reporting progress and no longer trips the build idle timeout.

MCP

  • On the per-robot surface, a refused member error now also names the other targets the robot fills with a member of that name.

Daemon

  • On Linux, the daemon's managed Zenoh router now ends the moment the daemon process dies, so an unclean daemon death no longer leaves a router holding its port.
v0.31.6 (Alpha): Record an endpoint's state-changing calls, answer a service with a picture, and read the first message that arrives after the read.

The call record

  • Declare a call_record in an exposure to publish a read-only tool that lists the last state-changing calls (mutating services and actions), newest first, with the client, arguments, outcome, and duration of each.

Services that answer with a picture

  • A service can declare a representation to answer its response's frame as an image beside the rest of the response, the way a picture tool does, with on_oversize to downscale a frame that exceeds max_result_bytes.

Reads return the next message

  • A topic read, and a picture tool, now answers with the first message the endpoint receives after the read, so a client that changes state and reads at once sees the result of its change, bounded by freshness.max_age_ms.
v0.31.7 (Alpha): The peppy platform commands are rebuilt around workspaces, projects, and enrolling machines in a project's cloud router.

Breaking changes

  • peppy platform list is removed; peppy platform peers now lists a project's router peers, with columns for peer name, status, certificate expiry, and id.
  • PEPPY_API_KEY personal-access-token authentication is removed; sign in with peppy platform login instead.
  • The zenoh.managed.federation block (with connect_timeout_secs) is gone from peppy_config.json5; remove it or the daemon refuses to load the config.
  • peppy platform status now reports this machine's enrollment and router link; use peppy platform whoami for the signed-in identity.
  • Run peppy platform login again after upgrading, because the previous credentials file is no longer read.

Signing in and enrolling

  • peppy platform login signs you in and then enrolls this machine in a project's cloud router, with --workspace, --project, and --no-enroll to steer it.
  • peppy platform enroll joins an already-signed-in machine to a project, --replace mints a fresh identity, and peppy platform unenroll removes it (--local-only deletes only the local record).
  • Enrolling or unenrolling restarts the daemon under the new identity and wipes the running node stack, prompting first unless you pass --yes.
  • The daemon renews the peer certificate automatically while you stay signed in, so an enrolled machine keeps its cloud-router link without manual steps.
  • peppy platform logout revokes the session and clears the selection but leaves the machine enrolled, so the daemon stays connected until its certificate expires.

Workspaces, projects, and the router

  • peppy platform workspace and peppy platform project (each with show, list, use, and clear) pick the default workspace and project the other commands act on.
  • peppy platform router restart applies pending changes such as a removed peer, and peppy platform router start starts a stopped router.
v0.31.5 (Alpha): New MCP picture tools, camera blobs, and progress-bounded actions; --nv GPU on Jetson; launcher adjustments reworked.

Breaking changes

  • A launcher option no longer accepts a bare list of fragments; write several files as { fragments: ["a.json5", "b.json5"] }, the object form that also carries the option's own adjustments.
  • A fragment may adjust only the instances it deploys; move writes to other instances into the launcher's adjustments, at the top level or under the option that selects the fragment.
  • An MCP read of a topic with a representation returns its frame as a separate typed blob, removed from the JSON document and its schema; resources/list now reports the blob's image MIME type.

MCP exposures

  • A topic with a jpeg representation can declare a picture tool that returns the latest frame as an image beside the rest of the message.
  • An action tool can set progress_timeout_ms instead of deadline_ms to bound a goal by its time without progress; it needs a feedback topic and no confirmation gate.
  • A cancelled action goal now returns the provider's result, in the tool error for a call or the status message for a task, and says why it was cancelled.

Containers

  • --nv containers on an NVIDIA Jetson now receive every driver library from the host's L4T container manifest, so CUDA and graphics run there as on desktop.

Actions

  • Unread action feedback buffers the newest messages, drops the oldest when full while always keeping the stream's end, and never blocks reading the goal's result.
v0.31.3 (Alpha): Repository refresh gains --strict and can pin a repository to a tag or commit; one_or_more axes run as launcher copies.
  • Run peppy repo refresh --strict to fail the command when any repository cannot be read, so CI and release checks stop instead of continuing.
  • A git repository's ref can name a tag or a commit that is not a branch head, and peppy repo refresh fetches it before reading the repository.
  • A launcher with a one_or_more axis in its components runs that axis as copies you can add and remove while its other instances keep running.
v0.31.4 (Alpha): The default hubs now track your Peppy version through the new `@{peppy-release}` ref.
  • New installs pin the default hubs with ref: "@{peppy-release}", which reads the peppy-release/<version> tag matching your Peppy version, so their content changes only when you install another version.
  • Set a git repository's ref to @{peppy-release} in repositories.json5, or pass --ref @{peppy-release} to peppy repo add and peppy repo exclude, to track your version's hub content.
  • Existing repositories.json5 entries are never rewritten, so a default hub already on main keeps reading main, which can now hold content that only a later Peppy version reads. To follow your Peppy version, set its ref to @{peppy-release}, or delete ~/.peppy/conf/repositories.json5, run peppy repo init to write the default entries again, then run peppy repo refresh.
  • Before you downgrade to a version earlier than v0.31.4, delete ~/.peppy/conf/repositories.json5 and run peppy repo init with that version: an earlier version cannot read ref: "@{peppy-release}", so it cannot read the default hubs.
  • After you install a different Peppy version, the daemon reads the @{peppy-release} repositories again at its next start, before it answers any request.
  • peppy repo list, search, and peppy repo show label a repository on @{peppy-release} with the ref it resolves to, such as reads peppy-release/v0.32.0.
v0.31.0 (Alpha): Serve every robot from one MCP endpoint, start named copies with a launch, and publish lossless 16-bit depth frames.

Breaking changes

  • peppy stack join now takes one OPTION:NAME argument in place of OPTION -i NAME; update commands and scripts that add a copy to a running stack.
  • peppy stack resolve previews joined copies with repeatable --join OPTION:NAME (addressed by --with NAME.option), replacing the removed --join, --join-name, --join-with, and --join-set-arguments flags.
  • A bound member's copy is now a CopyTag carrying the copy name and its fragment's instance id, not a plain name string; update readers of member.copy and of stack list --json.
  • The with_bound_producer_in_copy builder now takes the copy name and the fragment's instance id (running the producer as NAME_<id>) instead of the full instance id and copy name.

Copies at launch

  • peppy stack launch and peppy stack build accept repeatable, comma-separated --join OPTION:NAME to start named copies with the launch, addressed by NAME.option words and --place NAME@CORE_NODE.
  • A launcher deployments entry on a zero_or_more axis may list no copies, instead describing how every copy of that option is set up for later --join or stack join.

MCP exposures

  • An MCP exposure that declares robots becomes a per-robot surface: one endpoint serving every robot of the stack, where each tool names its robot and resources are published per robot.
  • Image representations add a lossless png16 codec for 16-bit single-channel depth frames, usable with on_oversize: "downscale", and now read frames labeled z16, mono16, or 16UC1.
  • An exposure target may select the same topic member several times, each entry with its own resource name, representation, and policies.
v0.31.1 (Alpha): On Linux, container builds authenticate to private registries with your Docker or Apptainer login.
  • On Linux, pull base images from a private registry by logging in with docker login or apptainer registry login before you build; peppy hands your credentials to Apptainer.
  • Builds that used Docker's browser login no longer fail at random with "incorrect username or password", because peppy leaves Docker's session tokens out of the credentials it gives Apptainer.
  • Log in or out while the daemon runs and the change applies to your next build, with no daemon restart.
v0.31.2 (Alpha): Launcher axes gain a `one_or_more` cardinality, and installation now supports only Ubuntu-based Linux and Apple Silicon macOS.

Breaking changes

  • The installer supports only Ubuntu and the Linux distributions built on it (x86_64 and aarch64) plus macOS on Apple Silicon; on Fedora, Arch, or any other system it stops before making changes.

Launcher copies

  • Give a launcher axis cardinality: "one_or_more" to run it as named copies with a floor of one: every launch must start at least one, from deployments or --join, and stack remove refuses the last.
v0.30.5 (Alpha): `peppy stack join` and `stack remove` now grow and shrink a running instance's producer and observer sets, delivered live to running nodes.

Breaking changes

  • peppy stack list --json now nests each slot_bindings producer under a producer key, with an optional copy key; update anything that parses that output.

  • Rust generated bound_producers() accessors return owned values (NonEmptyProducers, Vec<ProducerRef>) instead of borrowed slices, so bind the result to a variable before calling .first().

  • peppy stack join adds a copy's own instances to a running instance's one_or_more or zero_or_more producer or observer slot, delivering the grown set to the running node.

  • peppy stack remove takes the members a copy added back out of the running sets, and refuses a removal that would empty a one_or_more slot, naming it.

  • A running node's bound producer and observer sets, and its topic subscriptions, follow copies joining and leaving, so call bound_producers() or sources() at the point of use.

  • Generated set slots gain a bound_members() accessor returning each producer with the copy its instance belongs to, and Python gains a peppylib.BoundMember type.

  • peppy stack list shows the set members each copy added under Set members: and marks each bound member a copy brought with [copy NAME].

  • Standalone nodes gain with_bound_producer_in_copy and with_peer_pin_in_copy builders for a binding or pair whose instance belongs to a copy.

v0.30.6 (Alpha): A jpeg MCP image representation can render z16 depth frames as a greyscale picture over the depth range you configure.
  • A jpeg MCP image representation can render z16 depth frames as a greyscale picture, using a new depth_range field that sets the distances its shades span.
  • A federation join is refused when the machine of an instance whose set it grows is offline, while a removal proceeds and reports the sets it left unchanged.
v0.30.7 (Alpha): Add `peppy stack build` to build every node a launch would run, replacing the node stack without starting anything.
  • peppy stack build <launcher> builds every node a launch would run and replaces the node stack without starting any instance; it takes every flag peppy stack launch takes, including --rebuild.
  • A later peppy stack launch with the same launcher, placement, and --with words reuses those builds, so you can build onto a disk image that boots ready to launch.
  • After a build, peppy stack list shows each node Ready with 0 instances, and peppy stack join is refused until a peppy stack launch starts the stack.
v0.30.4 (Alpha): Action-backed MCP tools now run their goal inside the call for clients that lack the tasks extension.
  • A client without the MCP tasks extension can now call an action-backed tool: the goal runs inside the call, streams feedback as progress notifications, and cancels when the call closes.
  • An action-backed tool that requires confirmation still needs the tasks extension, and a client without it is refused with a clear missing-capability error.
  • Stopping a daemon now waits for its container to exit before the stop completes.
  • Stopping now waits for in-flight goals to finish tearing down before it returns.
v0.30.3 (Alpha): Join several robots into one simulation, each bringing its own model, plus a warning-free generated test harness.

Simulation

  • Join several robots into one simulation, each a copy bringing its own model; Isaac Sim and Waldo stand many at once, while MuJoCo stands one at a time.
  • Remove a simulated robot with peppy stack remove and only that robot leaves; the simulation stays running for the next join.
  • The simulation's model catalogue carries OpenArm v1, OpenArm v2, and SO-101, and a simulated SO-101 starts in its home posture with the jaw closed.

Generated test harness

  • The Rust test harness peppygen generates now compiles warning-free for a node that publishes nothing.
v0.30.2 (Alpha): MCP and node servers take a free port when theirs is held, and a joined stack copy inherits its option's settings.

Breaking changes

  • A zero_or_more axis option may be named in only one deployments entry now; a launcher that lists the same option twice is refused, so merge those entries into one.

Ports and endpoints

  • The built-in MCP server treats its port as a preference and takes an OS-assigned loopback port when another process holds it, so any number of MCP instances run on one machine.
  • Rust nodes can bind with peppylib::runtime::bind_preferred to take their chosen port, or an OS-assigned fallback on the same host when it is held, and learn which happened.
  • Endpoint blocks that stack launch and node run print are now tinted by field when color is enabled.

Launch files

  • A stack join copy inherits its option's deployments entry, taking that entry's with, arguments, and adjustments with the join's own --with and --set-arguments on top.

Networking

  • In the default "peer" topology a node session binds a network-reachable 0.0.0.0 listener on an ephemeral port; use "router" for a deployment that must not accept inbound peer links.

Core-node functions

  • stack.list now returns two more fields, copies and shutdown_grace_secs, beside its node graph and daemon identity.
v0.30.1 (Alpha): Nodes can now serve web pages and MCP endpoints, and peppy reports their URLs across its commands.

Breaking changes

  • peppy stack list endpoint output changed: the table adds KIND and LABEL columns and --json lists each endpoint as {label, kind, urls} rather than a URL string — update your parsers.

Serving pages and MCP endpoints

  • Declare a node's served endpoints under execution.endpoints in peppy.json5 — each with a label, a page or mcp kind, and a description — and announce each bound socket from setup with announce_endpoint.
  • peppy node run, peppy stack launch, and peppy stack join now end by printing the URLs each started instance serves, grouped under Web pages: and MCP endpoints: headings.
  • peppy node info and peppy stack list now show each running instance's endpoints with their kind, label, and every URL.

Auditing composed launches

  • peppy stack resolve now checks link rules for git-published nodes too, reading their manifests from the checkout cache peppy repo refresh fills instead of skipping them, without touching the network.
v0.30.0 (Alpha): A pairing slot can hold several peers through a declared cardinality, and `--nv` now renders through the GPU on Jetson boards.

Breaking changes

  • A pairing slot states that it may run empty with cardinality: "zero_or_one" instead of optional: true; replace optional: true on every depends_on.pairings entry (the default one still requires a pair).
  • peppy repo show and its --json output report each pairing slot's cardinality in place of the former optional flag; update any parser reading that field.

Pairing

  • A pairing slot can hold several pairs: declaring cardinality: "one_or_more" or "zero_or_more" pairs one instance with many peers, read through the generated peers() and published to with publish_to.
  • peppy stack list prints one row per pair tagged with each peer's copy, and stack join / stack remove add and dissolve pairs on a running multi slot.
  • An observer link can watch a single pair by naming its other end (watch: "peer_instance/link") instead of the whole source slot.
  • The generated test harness gives a multi pairing slot <link>_instances and <link>_members knobs that start one mock peer per member.

Containers

  • Passing apptainer_run_extra_args: ["--nv"] now binds the Tegra driver libraries, so a node renders or computes through the GPU on Jetson boards as it does on desktop NVIDIA hardware.

Other changes

  • While a build is quiet, each build-progress line names the last line the build printed and how long ago.
  • A daemon's derived core-node name now takes the form cn-{adjective}-{animal}.
v0.28.5 (Alpha): CPU a build burns now counts as build progress, so long silent compiles no longer trip the build idle timeout.
  • A %post step or a build_cmd that compiles silently no longer trips the build idle timeout: the CPU it burns now counts as progress alongside bytes written to disk.
  • Build progress feedback now appears during build_cmd runs too, and every progress line reports CPU time consumed as well as bytes written.
  • Peppy refuses a container bind path containing a : or a , on either side, because Apptainer's mount spec reads both as separators with no way to escape them.
  • Removing a stack copy that had paired into a stack instance's vacant slot now restores that slot to vacant, as the original launch declared it.
v0.28.6 (Alpha): `peppy repo index --check` now catches file copies that can never start and stops flagging ones their own constraints refuse by design.
  • peppy repo index --check now reports a file's copy whose own constraints refuse it under every admitted selection, since what the file deploys could never start; loosen a constraint or change the copy's with.
  • peppy repo index --check no longer flags a file copy under a stack whose selection its constraints refuse by design, matching how a join of that copy is judged.
v0.29.0 (Alpha): Named clock domains a launch selects per instance, hosted alongside wall time with no daemon restart.

Breaking changes

  • peppy service serve no longer accepts --clock-source=wall|sim; a launch now chooses its clock through domains, so remove the flag from your serve commands and scripts.

  • The per-instance framework: { use_sim_time } and framework: { publishes_sim_time } keys are gone; declare domains in a launcher's root framework.clocks and bind each instance with framework: { clock: "<domain>" }.

  • Standalone configuration replaces with_use_sim_time and with_sim_time_participants with a single with_clock, taking a ClockBinding that names the domain the node reads or publishes.

  • The generated test harness replaces its use_sim_time and sim_time_participants config with one clock knob set to wall, consumer, or publisher.

  • SimTimePublisher::for_node is renamed ClockPublisher::for_node, and it reports the single domain it supplies through domain() rather than a participant list.

  • One daemon hosts wall time and any number of simulated domains at once, so simulations and wall-time nodes run together and each launch picks its clock without a daemon restart.

  • peppy clock list shows every clock domain running across the federation: who publishes each, whether it has ticked, and how many instances read it, with --json for machine output.

  • peppy node run --clock <DOMAIN> binds an instance to a running domain and --publish-clock <DOMAIN> starts it as a domain's publisher; both also work with peppy node add --run.

  • peppy stack list adds a CLOCK column per instance, and peppy stack resolve reports the clock every instance of a plan reads before anything runs.

  • A producer binding, pairing, or observation whose two endpoints read different clocks is refused before anything starts, at launch, stack resolve, and node run alike.

  • Launcher adjustments gain a set_framework operation that binds a target instance's clock, letting one shared control or recorder fragment run on whichever domain selects it.

  • The generated clock module's now_ns reads whichever clock its instance is bound to, returning a simulated domain's last tick or the machine's own wall time.

v0.28.4 (Alpha): Generated Python code now decodes an unset optional field to None instead of failing when that field contains a fixed-length array.
  • Generated Python deserialization now reads an optional field only when it is present, so a message with an absent optional struct decodes to None instead of raising a fixed-length array error.
v0.28.0 (Alpha): Add and remove named launcher copies on a running stack, with steadier instance health and safer concurrent stack changes.

Breaking changes

  • Component axes no longer accept default or optional; add a deployments entry { <axis>: "<option>" } to pick which option runs, and use cardinality: "zero_or_one" in place of optional.
  • message_format no longer accepts the type aliases float, double, and str; use f32, f64, and string instead.

Repeatable copies

  • Declare a component axis with cardinality: "zero_or_more" to run its options as named copies you start, add, and remove independently under one launcher.
  • peppy stack join OPTION -i NAME adds a copy to a running stack, selecting its axes with --with, its machine with --place, and per-instance overrides with --set-arguments.
  • peppy stack remove NAME stops one copy and drops it from the stack, leaving every other copy and the stack's own nodes running.
  • peppy stack list and peppy stack list --json report each copy's option, host, selection, and instances.
  • peppy stack resolve previews a copy joined onto a launch with --join, --join-name, --join-with, and --join-set-arguments.
  • peppy stack reset --federated clears the launch from every machine it reached.
  • Fragments can declare their own component axes and reference other fragments across directories within a repository.
  • Constraint and adjustment when, requires, and forbids conditions accept a list of option names per axis, matching any of them.

Instance health and stack safety

  • A running instance is flagged unhealthy only after three consecutive missed health probes, and returns to healthy on the first probe it answers.
  • peppy node add, build, run, stop, and remove serialize with stack operations: refused while one holds the stack, and cancelled when stack reset runs after a cleanup window.
  • Cancelling a peppy node add, build, run, stop, or remove now stops the work on the daemon instead of letting it finish unattended.
v0.28.1 (Alpha): A daemon reserved for a launch now refuses `peppy node remove` and `peppy node stop`, not just `add` and `run`.
  • A daemon reserved for a launch now also refuses peppy node remove and peppy node stop, alongside the peppy node add and peppy node run it already blocked, naming the launch and coordinator holding the reservation.
v0.28.2 (Alpha): Generated peppygen packages now pin ruff's lint rules, so upgrading peppy no longer reformats the code peppy generates.
  • Generated peppygen packages now pin ruff's lint rule set in their pyproject.toml, keeping the generated code stable when the embedded ruff is upgraded.
v0.28.3 (Alpha): Environment variables now reach container nodes whole, and removing a stack copy restores the vacancies it filled.
  • Environment variable values that contain commas now reach container nodes whole, instead of being split into separate variables.
  • Removing a copy from a running stack now restores the vacant slots it had filled, unless another copy still occupies them.
  • A container bind mount whose source or destination path contains : or , is now refused with a clear error instead of being silently misparsed.
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