2026.09.7
Pre-releaseAdded
- Queues and addresses can now be created, destroyed, reconfigured, paused and
resumed from Studio, without dropping to theartemisCLI or a JMX console. A
command names a cluster, not a node: Artemis cluster nodes each own their own
queues, so the operation fans out to every live node and the result is a per-node
outcome rather than a single yes or no. A node that was not live is reported as
skipped, never as a failure, and re-running after a partial application converges.
Nothing is rolled back on a partial failure — a destroyed queue cannot be restored,
and a compensating create would be a different state dressed up as the original —
so the divergence is reported and left in your hands. - Every lifecycle command has a preview.
?dryRun=truenames the target nodes
and, for a destroy, the messages that would be lost on each, without touching any
broker. Destroying a queue destroys its messages, so it is counted against the same
safety.bulk-capas any other bulk destructive operation and needs the same
explicit override above it. - Four new permissions —
queue:create,queue:delete,queue:updateand
queue:pause— grantable globally, per environment, or per cluster. Holding
queue:purgedoes not imply any of them: emptying a queue and destroying it are
different authorities. They appear in the role editor with no upgrade step. - One MCP tool,
queue_lifecycle, covering every kind. It previews by default,
and turning the preview off for a destructive kind additionally requires a
confirmation matching the target's name. - A node's effective broker configuration is now readable on its own — the
settings it is actually running with, as the broker resolves them — at
GET /api/v1/clusters/{id}/nodes/{nodeId}/config, and to an MCP client as the
cluster://{id}/nodes/{nodeId}/settingsresource. Previously configuration could
only be seen by diffing two nodes against each other. - A paused queue is now identifiable as paused in the cluster's queue view,
including when it is paused on some nodes and not others.
Changed
-
managementWriteis no longer inferred from a read. It was reported as
available whenever a read-onlylistNetworkTopology()call succeeded, which proves
only that Jolokia is not under a read-only policy — not that any particular
operation is permitted. It is now unknown until a management write has actually
been attempted on that connection, available once one has succeeded, and
unavailable once one has been refused for an authorization reason, with the
broker.xmlthat would grant it.A connection previously shown as
AVAILABLEon inference alone will now read
UNKNOWNuntil its first write. This is a correction, not a regression — the
previous value was not evidence-backed. Write operations are still offered while it
is unknown, with the uncertainty stated: absence of evidence must not block you.
A write that fails for any other reason — an unreachable broker, an argument the
broker rejects — leaves the assessment alone, so one bad request cannot permanently
disable a button. -
Warning and danger text is legible in the light theme. Measured against the
WCAG 2.2 AA floor rather than assumed: warning text was 2.13:1 and danger text
3.84:1 on white, both under the 4.5:1 minimum for body text. They are now 6.67:1
and 5.46:1, keeping their hue. Purely graphical marks — chart axes, graph edges,
the alert dot — are unchanged, since the text floor does not apply to them. -
The MCP tool listing budget now scales with the number of tools rather than being a
fixed ceiling, and enum values and JSON body shapes moved out of the tool schemas
into astudio://toolsresource that a client reads only when it needs them
(ADR-0050). No tool was removed.
Added
- Clock and rr fix (b8a33d32)
Changed
-
Add queue and address lifecycle across a cluster (77ed26bf)
Studio could read every queue in a cluster and mutate every message in one, and
could not create, delete, pause or reconfigure the queue itself. That was the
largest remaining gap between an observability tool and a management tool, and
the one the product name already promises.A lifecycle command names a CLUSTER, not a node. Artemis cluster nodes each own
their own queues, so the operation fans out to every live node — resolved from
polled topology, never from configuration — and the result is a per-node outcome
list rather than a boolean. A node that was not live is reported as skipped, not
failed: it never received the command. Nothing is rolled back on a partial
failure, because a destroyed queue cannot be restored and a compensating create
would be a different state dressed up as the original; the divergence is
reported instead, and one audit row carries the whole fan-out.Verified against the broker rather than assumed, which changed the design three
times (ADR-0049, and the change's design.md records the method):- Every positional createQueue/updateQueue overload is deprecated as of 2.56;
the current API is JSON QueueConfiguration, and createQueue(cfg,
ignoreIfExists) supplies the already-in-state semantics directly. - updateQueue REPLACES rather than merges. A document omitting a field clears
it, so sending only an operator's changed fields silently destroyed the
queue's filter. The update path now reads, merges, and sends the whole config. - The filter is mutable; only the routing type is not. The spec asserted both
were immutable and has been corrected.
managementWrite stops being inferred from a read-only listNetworkTopology()
call, which proves only that Jolokia is not under a read-only policy. Nothing
depended on that guess until a create button did. It is now UNKNOWN until a
write has been attempted, AVAILABLE once one succeeds, and UNAVAILABLE only on
an authorization refusal — so one malformed request cannot permanently disable a
button. Evidence is persisted on the cluster, because the probe makes no write
and must not. Three existing screens gated on!== AVAILABLEand would have
locked operators out of working brokers; they now block only on a known refusal
and state the uncertainty otherwise.Also folded in, at the maintainer's request:
- A node's effective broker configuration is readable on its own, over HTTP and
as an MCP resource. ConfigReader already read exactly this for the two-node
diff and had no endpoint of its own. - The MCP listing budget scales per tool instead of a flat ceiling, and enum
members and body shapes move to a studio://tools resource a client reads only
once it has chosen a tool (ADR-0050). The flat 2000-token limit had no headroom
left, so any new capability would have failed it. No tool was removed.
Light-theme warning and danger text were measured, not assumed, and failed:
2.13:1 and 3.84:1 against a 4.5:1 AA floor. No shade of Mantine's yellow or
orange ramp reaches 4.5:1 on white, so the warning needed a dark amber literal.
Now 6.67:1 and 5.46:1; graphical marks stay on the bright ramp. - Every positional createQueue/updateQueue overload is deprecated as of 2.56;
-
Propose MCP tool grouping and progressive discovery (3bd1b31b)
The MCP surface is 14 tools and ~2100 tokens of tools/list, re-sent on every
conversation before a model has asked for anything. Four more roadmap changes
each add tools, so the listing roughly doubles on the current trajectory — at
which point cost matters and, more importantly, so does selection accuracy: a
model choosing between thirty flat tools picks worse than one choosing a domain
and then an operation. On a surface that can destroy a queue, that is a safety
property.This decides the shape before the surface gets there rather than after.
Deliberately a thin proposal — nothing is implemented. The answer depends on
what the MCP specification actually guarantees about tools/list_changed and what
the Spring AI MCP version here actually supports, and both are facts to verify
rather than assume. proposal.md records that the change must be brainstormed
first, the protocol and library checked through ctx7, tasks.md rewritten to
match, and only then implemented.design.md frames six open questions rather than answering them, and records the
constraints any answer must survive: no capability leaves the surface,
progressive discovery may not be mandatory, discriminators stay validated
server-side, and the budget stays enforced by a test.
Fixed
-
Accept a disabled interval in the poll() pausable-refetch helper (adb10625)
useMetricspassesnumber | falsetopoll()so an absolute (non-live)
chart range never polls, butpoll()only acceptednumber, so the frontend
build failed to typecheck. Widening the parameter keeps the pause seam intact:
afalseinterval stays disabled whether or not polling is paused.