Skip to content

v0.54.0

Choose a tag to compare

@underminedsk underminedsk released this 04 Aug 01:53
Immutable release. Only release title and notes can be modified.
808d8eb

Minor release: the MCP fleet-control surface gains the tools that act, and a security + reuse sweep lands across the event server.

Added

MCP fleet control gains its write half (#944). POST /mcp on the event-server Worker adds bobi_read_transcript, bobi_send_message, and bobi_lifecycle alongside 0.53.0's three read tools, so an agent can act on a fleet rather than only observe it. No new authority and no new admin vocabulary — the same FLEET_OPERATOR_TOKEN gate runs before any tool body, and the tools drive the same nine commands the sidecar already answers.

Commands resolve through a bounded server-side wait (5s, MCP_COMMAND_WAIT_MS, 0 disables): fast commands return in one tool call instead of three, slow ones return status: "pending" plus a command_id. pending means not-yet-answered, never failed.

Three behaviors are stated in the tool descriptions because an agent would otherwise believe the opposite: bobi_send_message does not return the agent's reply (the supervisor resolves chat only when the whole turn ends, minutes later — read it back with bobi_read_transcript); transcript output is untrusted third-party content, returned in its own block between explicit warnings; and bobi_lifecycle requires a reason, recorded as an audit control, with self-targeting allowed and annotated rather than refused.

Fixed

  • Attribute injection in the agent-reply markdown renderer (#942) — agent output could close an href attribute and land a live event handler, and agent replies are prompt-injectable from anything the agent reads.
  • Unvalidated register payload on the unauthenticated mint path (#942) — a bare string registered one subscription per character; a non-string element threw after an orphan bubble had been persisted.
  • Unbounded request-body buffering (#942) — the 413 arrived after the memory was spent, and on a non-loopback bind the peak was unauthenticated. Now capped at 8 MiB (BOBI_ES_MAX_BODY_BYTES).
  • Slack file uploads in DMs and thread replies never arrived (#945) — every file_share-subtyped message was skipped before classification.
  • The circuit breaker's pause buffer was unbounded and never released (#945) — a conversation that tripped then went quiet held its buffer for the life of the process.
  • /channels/send accepted required text and delivered it nowhere (#945) — on WhatsApp the user got the file and never the sentence explaining it.
  • Concurrent Slack workspace registrations raced away a bot's signing secret (#945) — a fleet roll restarting both agents could 401 one app's inbound events.

Changed

  • The release workflow publishes the pins the image dispatch needs (#943).
  • Event-server reuse sweep (#945) — eight duplicated or dead surfaces converged.

Full detail in CHANGELOG.md.