Skip to content

v0.16.4

Choose a tag to compare

@github-actions github-actions released this 11 Aug 04:46
· 566 commits to main since this release

Agent-to-agent messaging, a trust gate that covers the settings that can run code, structured failure classification, and build provenance.

Full detail for every item is in CHANGELOG.md — this is the readable summary.

Security

  • [collab]'s channel switches are forced to the user's global value. A project's .plumb/config.toml is an untrusted surface — a cloned repository ships one — and [collab] was missing from the list of sections a repo may not set for itself, so a clone could open intents, mailbox, cross_project or knowledge_handoff on its own. (Already superseded on main, shipping in the next release: these are gated on plumb trust instead, so per-workspace chat settings work again — with the user, not the repository, holding the switch.)
  • A project's .plumb/config.toml could run arbitrary code, and could open settings it should not. plumb trust now covers a project's [lsp.<lang>] and [git] settings — the ones that decide what gets executed — rather than only the obvious exec fields.
  • A fold-variant key escaped the trust gate entirely. go-toml folds a table name to a struct field the same way it folds a field name, so a case-variant [lsp.<lang>] decoded into the config while an exact lookup left it out of the trust spec. Matching is now case-insensitive.
  • plumb trust now asks. It previously printed the disclosure and granted in the same breath.
  • protected_branches warned only on an empty list, though the list is the complete set — a shortened one is the more likely mistake.
  • A published threat model: docs/threat-model.md names plumb's assets, trust boundaries and non-goals.

Added

  • The mailbox is a real agent-to-agent conversation channel. leave_note + check_messages: messages ride on any tool result so you receive them while working, check_messages({wait_seconds}) blocks server-side so you can hand your turn to a peer instead of polling, replies thread by conversation_id, and a thread is capped by an exchange budget. Same-workspace by default; cross-project delivery is the recipient's opt-in.
  • Tool failures carry a stable, machine-readable classification. Write, boundary, rate-limit, language-server and git refusals are all classified, a failing git child carries its own kind, and a failed tools/call carries the classification on the wire. Classification happens exactly once per call, at the MCP dispatch boundary.
  • plumb setup codex --lean / --lean for Gemini CLI write a client-side tool allowlist, and plumb doctor grades every one of them.
  • A project config plumb is ignoring now says so, in four places, rather than being silently skipped.

Changed

  • Build provenance. A binary can say which source commit it was built from: plumb version --json prints a machine-readable report and daemon_info gained a source commit: row. Both stampers measure source-tree dirtiness instead of asserting it, a revision that is not a plausible SHA is treated as no stamp, and "dirty state unknown" no longer renders as clean.
  • plumb stats --failures (a breakdown by kind) and plumb stats --since <age> (scoping the whole command), with a "Failures by Kind" widget on the TUI dashboard. Stats schema user_version 16.
  • The TUI settings editor exposes the [git] tier rows and the exec-deciding fields.
  • The plumb-diagnose skill teaches the structured lane first.

Fixed

  • Doc comments in the topology index. Zig symbols carry their /// span; a //! container doc no longer attaches to the following declaration; Python methods in a class body and every decorated declaration carry theirs; and a comment trailing a body's header line is no longer collected as the first doc line.
  • Several plumb doctor corrections: no longer suggesting a repoint that would overwrite a client-side allowlist, naming a mistyped Codex allowlist correctly, not claiming a backup that may not exist, and a removeKey canary that was a no-op on Codex.
  • session_start no longer steers a --lean client at tools it cannot call.

Install: brew install plumbkit/plumb/plumb, or grab a binary below (macOS and Linux, arm64 and amd64).