MaestroHub 2.4.0 Release Notes
MaestroHub 2.4.0 is a major release that brings pipelines to life on the canvas with real-time execution feedback, ships a complete redesign of the authorization stack with custom roles and license-aware permissions, adds a new Omron FINS connector for industrial PLCs, introduces a dependency-aware deletion experience that prevents accidental data flow breakage, redesigns the monitoring module end-to-end across both Lite and Enterprise editions, and lands dozens of UX, performance, and reliability improvements across every surface of the product.
Highlights
- Live pipeline execution — Manually triggered pipelines now stream node-by-node progress straight to the canvas and the execution-history panel in real time.
- Authorization system redesign — A full rebuild of the permissions stack: custom roles, sharing and transfer of resources, license-tier-aware role catalog, runtime gates on functions and topics, and pipeline-as-subject identity.
- Omron FINS connector — End-to-end support for Omron CV / CS / CJ / CP / NJ / NX series PLCs over UDP, with read, write, atomic bit control, and clock probe operations.
- Unified deletion preview — Every entity (connection, function, pipeline, model, topic, dashboard) now consults a shared deletion planner before delete, surfacing dependents and downstream impact before anything disappears.
- Monitoring overhaul — Label-aware metrics store, generic query API, RED middleware on every microservice, redesigned overview page, and runtime gauges across all 15 Enterprise services.
- Entity-level insights — The home-page Risks tab is now a structural-health view that groups signals by urgency (Now / Soon / Later) per entity, with self-calibrating thresholds and per-user snoozes.
- UNS topic search — Lexical and fuzzy search across the ISA-95 topic hierarchy, exposed to operators in the admin UI and to AI agents through MCP.
- Deleted topic visibility & restore — Toggle a deleted-only view of the topic tree and restore individual topics or whole subtrees, with audit-grade event consistency.
- Expanded bulk operations — 15 new bulk endpoints across connections, functions, pipelines, models, dashboards, and users (start/stop, enable/disable, label, clone, delete).
- Read group: match by label + onChange mode — Target functions dynamically by label chips, and emit only when values actually change.
- Helm split into two namespaces — Enterprise deploys now separate
maestrohub(product) frommaestrohub-deps(bundled third-party services) for cleaner RBAC and operations. - In-place trial extension — Expired Lite trials can be extended for another 2 hours from the License page, no restart required.
Live Pipeline Execution
When a user clicks a manual trigger node's hover action, the canvas and execution-history panel now render in real time as the pipeline runs.
- Live canvas — Edges pulse, the running node breathes, completed nodes show inline timing chips, and intermediate values are visible as they flow.
- Live history panel — Execution rows fill in as steps complete instead of only after the run finishes.
- Per-tab isolation — Live events are scoped to the WebSocket connection that initiated the run, so other tabs and other users on the same pipeline don't see your data leak across.
- Multiple manual triggers per pipeline — Pipelines can now have more than one manual trigger node. Each one runs independently from its own per-node action; only the reachable subgraph executes.
Authorization Redesign
A complete rebuild of MaestroHub's permission system based on a 51-ADR design specification. The result is a cleaner, more powerful, more honest model.
What's new
- Custom roles — Create your own roles by combining permissions from the catalog. Reserved name protection, cycle and depth guards built in.
- Two-tier built-in role catalog —
Personaroles (Member, DataEngineer, PlantOperator, Analyst, SecurityAdmin, ComplianceAuditor) andFeatureroles (Connect.*, Automate.*, Data.*, Platform.*, Secret.Revealer, LogReader). Members get a sensible default on org-join. - Resource sharing — Share a connection, function, or pipeline with another user, transfer ownership, or grant time-limited co-ownership directly from the resource page.
- Pipeline-as-subject — Pipelines now have their own identity (
pipeline:<uuid>) and are auto-granted the precise permissions they need at save time. UNS publishes from a pipeline are now properly enforced — no more "admin to make it work" workarounds. - Runtime gates —
function:execute,topic:publish,topic:subscribe, andtopic:readare enforced at the engine and scheduler hot paths, not just at the HTTP edge. - License-tier-aware —
advanced_access_controlgates the full role catalog. Foundation customers who buy the feature flag get Enterprise-equivalent authz without any code change. The UI hides what the license doesn't grant. - Frontend permission awareness — Sidebar items, action buttons, and node palettes filter by your actual permissions. The "Test Function" button now correctly appears only when you can execute it.
- Audit classification — Every authz event is classified for compliance reporting.
What's better
- Casbin wildcard fallback so admins assigned in domain
*work across every org domain. - Action vocabulary is now consistent end-to-end —
GetAllowedActionsreturns the full verb set for a resource, not just CRUD. - Foundation Member persona broadened to cover connection and secret build verbs plus runtime ops.
Documentation
The full design — including the 51 ADRs covering grammar, identity, entity catalog, role model, sharing, audit, denials, license tiers, and production hardening — is checked in under docs/architecture/authz/decisions/.
New Connector: Omron FINS
End-to-end support for Omron's Factory Interface Network Service over UDP. Covers CV, CS / CJ, CP, and NJ / NX series PLCs.
- Memory areas: CIO, WR, HR, AR (with read-only 0..447 guard), DM, EM (banks 0–12), TIM_CT_PV / FLAG, TASK_STATUS.
- Data types: Bit, Word, DWord, Real, Bytes, String — with bit-level addressing.
- Operations: read (multi-point coalesced), write (typed), atomic bit control, real-time clock probe.
- Routing: configurable destination + source network/node/unit, byte order, retries with backoff, local-port bind with ephemeral fallback.
- Pipeline nodes: four nodes —
connected.omron.read / write / bit.control / read.clock. - UI: Connect form with Basic / Routing / Advanced tabs, per-operation function forms with form-level validation and per-point Test buttons.
Dependency-Aware Deletion
A unified deletion planner now powers every entity-delete in the product. When you (or a bulk operation) try to delete something, the system checks the dependency graph first and tells you what will break.
- One shared planner — Connections, functions, pipelines, models, topics, and dashboards all consult the same
DeletionPlanner. - Three blocking levels per edge —
hard(blocks delete),soft_autoheal(warns — e.g. topic auto-recreates),informational(just FYI). - Transitive impact — Deleting a pipeline that publishes to a topic now warns that downstream dashboards will go stale, not just that the topic loses a publisher.
- Preview dialog — Single and bulk delete (connections, functions, pipelines, models, topics) all share a preview dialog showing entities collapsed by type, friendly names instead of UUIDs, dependent counts, and a hidden Delete button when blocked.
- Admin force-delete — System / Organization admins can override warnings or blockers via
?ignoreWarnings/?ignoreBlockerson the API. - System-protected entities — UNS version roots (
mHv1.0,mHv2.0) are now system-protected and cannot be deleted. - Bulk delete fixes — Bulk endpoints return per-item structured codes instead of a generic toast, and pre-deselect blocked rows.
This closes a long-standing silent breakage: deleting a pipeline that fed dashboards used to succeed without warning. It now tells you exactly what will go quiet.
Monitoring Overhaul
The monitoring module was rebuilt end-to-end. The Lite and Enterprise editions now share a single label-aware query API; every microservice now emits RED metrics; and the overview page surfaces what operators actually need.
Foundations (Phases A–G)
- Label-aware metrics store with hard cardinality cap and LRU/drop-new admission —
http_requests_total{service, status_class}is now expressible in Lite without a custom shim. - Generic query API —
POST /monitoring/query_range,POST /monitoring/query,GET /monitoring/metric-names,GET /monitoring/labels/:metricwith closed-set aggregations (sum,avg,rate,max,min,count,p50,p95,p99). - HealthService — first-class system-health API with a 5-second cache, shared rule evaluator (alerts plug in as a second consumer without rewriting), and per-module probing.
- InfrastructureProvider — nodes and pods endpoints for the Enterprise infrastructure dashboard.
- Capabilities endpoint — frontend can ask the backend what shapes of data this deployment supports, no more edition-detection guessing.
- RED middleware on every microservice — every HTTP request emits standard request/duration/in-flight metrics with zero per-service wiring.
- Generic OTel sampler — anything instrumented anywhere is queryable through the same endpoint in both editions.
Enterprise infrastructure dashboard
- Runtime gauges on all 15 microservices via the shared bootstrap.
- Backend-driven pod categorisation —
kubectl get nsis now the truth, not a UI heuristic. Helm split intomaestrohub(16 product pods) andmaestrohub-deps(14 dependency pods). - Node-aggregated cluster stats so the cluster header agrees with the node cards below it.
- Stateless services no longer emit misleading container-overlay disk numbers.
- Disk-join made IPv6-safe; cluster-header values are now percent-only for legibility.
Lite stability
- Tiered ring buffer (1 hour @ 5 s + 24 hours @ 1 m) with drop-new admission replaces the previous LRU eviction churn that was wiping pipeline charts on long-running deployments.
- Restart-survives metrics now persist correctly across the full retention window.
Overview page polish
- Engine and System tab charts adopt the UNS dashboard look — vertical gradient fills, soft glow under each line, dashed crosshair guides, dark blurred tooltip with right-aligned bold values.
- Charts now distinguish "no data" from "measured zero" — empty series no longer flatline at zero misleadingly.
- 10 m / 15 m chart steps widened to 1 m to kill rate aliasing.
- Chart windows are now clock-aligned with an honest resolution badge.
- Pipeline cards on the overview redesigned to four engine charts and a deduplicated System tab.
UNS Improvements
Topic search (Phase 1)
A new lexical and fuzzy search subsystem over the ISA-95 topic hierarchy. Hybrid retrieval, backfilled and kept in sync via the existing event bus.
- Operators can find topics by partial paths, synonyms, or natural language ("find all mixer pressure sensors in Berlin") instead of needing exact paths.
- MCP agents get two tools —
uns_semantic_find_topicsanduns_describe_topic— for AI-assisted discovery without hallucinating topic paths. - One admin HTTP endpoint for the UI search box.
- Ships disabled by default; opt in per environment. Phase 2 will add dense embeddings on the same architecture.
Deleted topic visibility and restore
- "Show Deleted" toggle in the tree dropdown switches to a deleted-only view with red icons and strikethrough text.
- Restore action on right-click — preview which parents will auto-restore and how many children are below; choose whether to cascade-restore.
- Auto-restore on next publish — unchanged behavior, but now publishes a
TopicRestoredevent so search index, dependency graph, and config cache all stay consistent. - Paginated deleted view — same lazy-load tree as active topics, no more unbounded loads as historical deletions accumulate.
Tree pagination & depth safety
- Topic tree now requests pages instead of pulling every topic in the org. Browsers no longer freeze on tens of thousands of topics.
- Topic depth is capped to prevent automated tools from creating hundreds-of-segments-deep paths that can't be rendered.
- Search results are no longer silently capped at 100; the UI loads all pages.
- First-mount expansion race fixed — children load reliably without a collapse / re-expand workaround.
Data Explorer
- Live data fixed — the WebSocket envelope is no longer double-wrapped; live messages now reach the explorer.
- Time-range buttons reworked —
15S / 1M / 1H / 6H / 24Hfor high-frequency inspection (default still1h). - Downsampling badge — the UI now explains when data is bucketed, what bucket size was used, and why.
- Clear messages button now wired correctly.
Embedded broker
- MQTT-over-WebSocket is back as an opt-in listener (default port 8083), gated by a
config.yamlflag and surfaced in the UNS settings tab. Disabled by default to avoid accidental exposure.
Insights & Dependencies
Entity-level insights redesign
The old Home-page Risks tab is now a per-entity insight feed grouped by urgency.
- Per-entity signals — Connections, functions, pipelines, topics, dashboards each get structural-health signals.
- Three-bucket urgency —
NOW(silent breakage),SOON(structural risk),LATER(hygiene). - Per-user snoozes — Snooze a signal for yourself; it self-clears when the underlying condition goes away.
- Topic-direction fixes — Dynamic UNS topic edges now carry the correct publisher/subscriber direction, so topic-direction insights are reliable for pipelines that resolve topics from expressions.
Self-calibrating thresholds
Insight rules used to use fixed numeric cutoffs that didn't fit small homelab installs or fleet-scale industrial deployments. They now derive their cutoff from each org's own distribution: max(minimum-floor, p95, 2 · median).
- Zero user-facing config — rules scale automatically with the shape of your fleet.
- Collector-pattern exemption — pipelines that pull ≥ 80 % of their upstream from a single connection (OPC pollers, Modbus polling, historian collectors) are no longer flagged as "high upstream reach." Those are legitimate industrial patterns.
- Reliability honesty —
topic.starved/topic.void/topic.deadsignals removed because external MQTT clients and bridged brokers are invisible to the graph; they were producing false alarms. - Reasoned splits —
dashboard.broken_upstreamnow distinguishes silent breakage (only publisher is a disabled pipeline) from hygiene (no MaestroHub publisher, but external publishers may exist).
Export / Import: Data Models
- Both export and import paths now properly handle data models. Exports actually populate the models slice; imports prompt for skip/rename on collision; the import wizard's progress bar no longer sticks at 0%.
- Dashboard name collisions are now detected during validate, not after import starts.
Pipeline Engine
Read group node enhancements
- Match by Label — A third selection mode, alongside "All Functions" and "Select Functions". Pick functions by clicking label chips discovered from the connection (multi-select with AND across keys, OR within a key). Available on Modbus, OPC UA, S7, EtherNet/IP, and BACnet read groups.
onChangeoutput mode — Mirrors the MQTT trigger contract. Successful reads with unchanged values are filtered out per output key; failed reads always pass through so stuck devices stay visible. When everything is suppressed and nothing failed, the node buffers and downstream is skipped.
Performance hardening
A full audit of the pipeline-execution hot path landed across two large omnibus PRs (#1796, #1798). Highlights:
- OTel attribute sets cached per dimension tuple — Record* hot path down to 85 ns/op, 2 allocs/op.
- In-memory state store sharded into 16 stripes — verified ≥ 1.6× parallel speedup; unlocks higher trigger-dedup throughput.
- ParallelExecutor and ExecutionContext pooled.
- Iterative BFS with descendant-skip replaces recursive walks.
- SQLite hot path: dead-letter queue, transaction chunking, prepared-statement reuse, configurable busy-timeout.
- Per-pipeline concurrency limit (configurable, raised default to 5000) prevents runaway pipelines from overwhelming the engine.
- Execution save debounce (1 / sec) and a new
"none"execution-persistence level (zero DB writes on success) for high-frequency pipelines. - Eventbus dispatch latency and dropped-events metrics, plus a queue-saturation health signal (p95 wait duration) for early overload detection.
Cache and trigger correctness
- Pipeline cache and trigger dedup state are now invalidated on enable/disable, fixing a subtle bug where toggling a pipeline could leave stale state in memory.
- Auto-cleanup: disabling a pipeline now wipes per-node trigger and read-group state automatically.
- MQTT overlapping subscriptions no longer cause duplicate pipeline dispatch — a critical correctness fix for any pipeline whose topic filters overlap.
- Aggregator and sibling path-syntax executors no longer crash on single-predecessor input —
ResolveInput's array wrapper is now unwrapped where the executor expects a map. - Outer-loop
$itemis now visible in the Test Node panel for nodes after an inner LoopEnd. - Connection initiator is properly propagated through trigger dispatch.
YAML connector definitions
All 30+ protocol connectors converted from hand-written Go factories to declarative YAML + a generic Adapter pattern. Removes ~15 k lines of boilerplate config and validation code while preserving exact runtime behavior.
Other engine fixes
- Manual trigger now forwards the configured
outputDatapayload on fire (previously silently dropped). - Function arguments are correctly preserved across function create / update — the form no longer bounces back unsaved.
- "Warn about unsaved changes" prompt added when toggling pipeline enable/disable.
Bulk Operations
15 new backend endpoints, all permission-gated, plus the frontend wiring to drive them:
| Area | New bulk endpoints |
|---|---|
| Connections | start, stop, label, clone, function-label |
| Pipelines | enable, disable, label, clone |
| Models | delete, label |
| Dashboards | delete |
| Users | activate / deactivate |
The existing bulk/delete flows for connections and pipelines were refactored to share the new helper. Bulk delete on connections, functions, and pipelines now use the dependency-aware preview dialog — selecting 50 items shows you which can be safely deleted, which are blocked, and why.
Dashboards
- Kiosk mode — Full-screen, chrome-free dashboard view. Hides the header, sidebar, tab bar, and sidebar toggle. Subtle exit button at bottom-right; Escape key also exits.
- Deleted dashboard tabs removed from the tab bar automatically.
- Panel suggestions now include schema-defined fields whose recent values happened to be null (previously invisible to the suggestion engine).
- Panel placement — Automatic grid compaction disabled. Panels stay where you place them.
- Per-panel data shape contracts — Panels declare the data shape they consume (
renderable,numeric,custom). One single-pass entry builder replaces the previous two-walk pattern. Custom ECharts panels can now read rawrecord.valuefor arrays / nested objects without a workaround. - Insights and detail panels aligned as floating cards.
- Object metadata values rendered as JSON instead of
[object Object].
OPC UA
- Paginated and filtered monitored-nodes form — Instead of mounting 10 K + Card rows at once, the form now paginates and supports identifier substring search. Matches the data-table pagination footer used elsewhere.
- Auto-generated certificate preserved across connection updates — previously regenerating on every save broke device-side trust.
Connectors
- Duration units canonicalised on round-trip — exporting and re-importing a connector no longer broke validation due to nanosecond/millisecond mismatches; values are rewritten back to the schema-declared unit on validate.
- Config validation errors return 400, not 500 — and the import-failure UI shows what actually failed.
retryDelayunit consistent across connector schemas.- Templating coverage —
canBeTemplatednow flows from connector YAML through the MCPexplore_protocolstool, so AI agents see exactly which fields accept((paramName))placeholders. REST, SQL (MSSQL/Oracle/MySQL/Postgres/Databricks SQL), MQTT, OPC UA, S7, BACnet, EtherNet/IP, RabbitMQ, Kafka, Redis, MongoDB, and Modbus are all annotated. - Plain hostnames now allowed in REST connector base URL validation.
- S7 quick-add supports custom size for string/wstring types.
RuntimeEnabledflag removed from connectors — runtime initialization is inlined and predictable.- S7 / BACnet / EtherNet/IP metadata consolidated into YAML.
- Minor REST protocol bug fixes.
MCP / AI Tools
- Templating support advertised correctly across all connector tool descriptions, with a clear
((paramName))syntax note. - Topic tools updated to advertise the required
mHv1.0/schema prefix in examples. manage_license historyandmanage_access list_roles— both were broken outright (returned bare slices that MCP clients reject); now return proper record-shaped responses.- Pipeline
Get, scheduler dispatch, and UNS topic publish all corrected silent-failure paths surfaced by exercising the MCP surface against the running app. - Read group tool descriptions updated to reflect label-match mode.
- Model Actions added; topics tool descriptions clarified.
License
- In-place trial reset — Expired Lite trials now show an "Extend 2 hours" button on the License page and the expired-trial banner. Clicking it solves a small proof-of-work challenge (~1 second on a laptop) and resets the trial in place — no restart, no dropped connector sessions, no phone-home. Fully air-gap-safe. Each reset is logged with the instance fingerprint.
- Proof-of-work is HMAC-signed and locally verifiable; no external dependency.
Auth & Security
- Hardcoded dev secrets removed from the Lite Dockerfile
ENVsection. - Custom WebSocket header (
X-MH-WS-Connection-ID) allowed in CORS preflight, unblocking the live-execution feature. - Access denied page now refetches org queries on retry, so granting access mid-session no longer requires a hard refresh.
- Enterprise auth — JWT middleware, LDAP / SAML routes, and WebSocket origin handling fixed for split-namespace Helm deploys.
- Helm proxying —
/api/v1/profileand/api/v1/usersnow route to the auth service correctly.
Frontend Foundations
- Unified API client — Every API method now returns the full
StandardApiResponse<T>envelope. The HTTP layer no longer editorializes shape; callers decide how much of the envelope they need. Surfacesmeta,result, anderror.codeon every response. - Frontend Fast Refresh compliance — Pages and components refactored so HMR works reliably across the UI.
- Unified loading UX — Shared
QueryBoundary,PageSkeleton,EmptyState,ErrorState,SlowLoadingHint,GlobalProgressBar, plus a rotating domain-aware micro-copy catalog. - Organization switch no longer triggers a full-page refetch flash; React Query keys include the org ID so caches partition correctly.
- Multi-tenant metrics — UNS health and monitoring overview no longer leak global counts; per-org filtering enforced at the provider layer.
- Overview page skeleton matches the actual layout instead of a generic spinner.
Deployment & Operations
- Helm chart split — Enterprise deploys now use two namespaces:
maestrohub(product, 16 pods) andmaestrohub-deps(Postgres, ES, NATS, EMQX, kube-prometheus-stack, fluent-bit — 14 pods). RBAC, network policy, and resource-quota boundaries land for free;kubectl get nsis now the source of truth. - Public Artifact Registry —
maestrohub-liteis now pushed tous-docker.pkg.dev/maestrohubtests/maestrohubwith anonymous read enabled (multi-arch manifest tags only). Unblocks downstream distribution channels. - Portainer App Template — Draft
docker-compose.ymland Portainer v3 template entry for MaestroHub Lite, validated against the upstream schema. No upstream PR opened yet; intended for the upcoming submission toportainer/templates@v3. - Showcase deploy target — Lite pipeline now publishes to a dedicated showcase environment with a
build_from_devmode (default on) for fast iteration, and a release-tag mode for promoted images. - Docker base image CI/CD — New automated multi-arch (amd64 + arm64) base-image build and push workflow, version-prefixed deploy tags.
- Local-dev kind workflow — First documented end-to-end path to run the full stack on Docker Desktop's kind-based Kubernetes with a local registry.
- DevOps environment & release strategy guide — Self-contained
deployment/devops-guide.htmlcovering current state, desired two-environment model, weekly release flow, and per-environment playbooks.
Documentation
- Getting Started rewritten as a guided 8-step journey with aligned numbers, videos / images, and a "try right now" action block per step.
- Authorization ADRs — 51 architecture decision records under
docs/architecture/authz/decisions/covering grammar, identity, entity catalog, role model, sharing, audit, denials, license tiers, and production hardening. - Live-execution ADRs — 12 ADRs under
docs/architecture/live-execution/decisions/documenting the design. - Energy Monitoring Dashboard guide — New DFS guide.
- REST API — Personal Access Token documented as a quick-start auth option.
Notable Bug Fixes
A non-exhaustive list of correctness fixes that landed in this release:
- MQTT duplicate dispatch — Overlapping subscriptions on the same connection were causing every MQTT-triggered pipeline to fire N² times per real publish. Fixed at the in-memory fan-out layer.
- UNS Data Explorer live data silently dropping every frame because of a double-wrapped event envelope.
- UNS topic tree freezing browsers on tens of thousands of topics — pagination + depth cap fixed it.
- Insights "Risks" tab producing false alarms from external-publisher topics — signal taxonomy reworked.
HardDeleteSQLite race under file-backed configurations — single-connection enforcement matches the in-memory contract.- Identity-providers GET-only auth skip — POST/PUT/DELETE now require auth so SSO provider
created_byfields are populated. - Function arguments stored under
argumentsin node config (renamed fromparameters); backend remains backward-compatible with all three legacy keys. - Dynamic UNS edges carry direction correctly so topic-direction insights are reliable.
- Trigger dedup consolidated into a single shared helper across all 5 connector trigger executors with per-node dedup config.
- 30+ real bugs surfaced and fixed across the value-driven test sweep — including SQL injection in log filters and exporters, credential masking gaps, scheduler wiring, validator determinism, and more.
Backward Compatibility
This release introduces the new authorization model alongside the existing one. Existing role assignments, custom policies, and pipeline configurations continue to work without changes. New features (custom roles, sharing, runtime gates) opt in per-deployment as you adopt them.
All API endpoints, function signatures, config fields, and CLI flags from 2.3.x continue to work. New fields have sensible defaults so existing configs run unchanged. Database migrations are additive.
Getting Started
Download a native binary or pull the Docker image and follow the Getting Started guide to have MaestroHub running in minutes.