Skip to content

perf(stagehand): take the hot list from the broker, without REST checks - #575

Merged
stakach merged 2 commits into
developfrom
feat/stagehand-trust-mqtt
Oct 15, 2026
Merged

stakach merged 2 commits into
developfrom
feat/stagehand-trust-mqtt

Conversation

@stakach

@stakach stakach commented Oct 15, 2026

Copy link
Copy Markdown
Member

Why

Stagehand was slow because it double-checked every MQTT alert over REST. That check was covering for two bugs in how stagehand read the broker, not just for bad broker data:

  • History kept, not latest: every message was appended to a list, and a topic's previous value was never replaced. A module that went connected: false and back to true still matched "disconnected" through its old entry.
  • Removals never read: source removes a topic by publishing an empty payload to it. JSON.parse('') threw, so deleted modules stayed listed. This is the "alerts for deleted modules" field report.

Then on every message (10ms debounce), each alert was checked one at a time with a module-list query and a systemModuleState read per comparison.

Change

  • New broker-alerts.ts (pure functions): keep the latest value per topic, treat an empty payload as removal, and work out alerts from those values alone.
  • The REST checks and their module cache are removed from DashboardsService, which goes from 827 to about 390 lines.

Fixed along the way, previously hidden by the REST check:

  • GT/LT/GTE/LTE compared expected OP value, the wrong way round. They now compare value OP expected, the same semantics as the old REST check, including string coercion.
  • Sub-keys: comparisons now read a status's sub-keys (left.keys).
  • Multi-condition alerts: matches must all come from the same system. Before, a match on one system could pair with a match on another.
  • Stale values: values are cleared on connect and on resubscribe, since the broker hands every retained value back. A topic removed while disconnected can't linger.

Depends on

This trusts the broker, so it needs source with PlaceOS/source#65 and #66 (1.22.2 or later) on the backend. Without them a deleted module's topics may never be removed, and the reorder bug returns.

Testing

  • Unit: 219 pass, including new broker-alerts.spec.ts (removal, operator direction, sub-keys, per-system grouping) and service tests that a value change and a removal update the alerts with no REST calls.
  • e2e (local): 16/16 against source master. New SH-HOT-03: two disconnected Displays, then the first is deleted. The other must be listed as Display_1 with nothing at Display_2, and reconnecting it must clear the list, with no module-list or module-state requests. It fails against develop's stagehand, where the deleted module stays listed.
  • tsc (app + spec) and oxlint: no new findings. nx build stagehand passes.

🤖 Generated with Claude Code

The hot list kept every message the broker sent, so a module's earlier
values still matched after it changed, and could not read the empty
payload source sends when it removes a topic, so deleted modules stayed
listed. Each alert was then checked again over REST, a module list and a
state read per alert, on every message, one at a time.

Now the latest value of each topic is kept, an emptied topic is removed,
and alerts are worked out from those alone (broker-alerts.ts). The REST
checks and their module cache are gone. Also:

- GT, LT, GTE and LTE compare the status with the expected value; they
  were the wrong way round, hidden by the REST check
- comparisons read a status's sub-keys
- the conditions of one alert must hold on the same system
- values are cleared on (re)subscribing, as the broker hands every
  retained value back

SH-HOT-03 covers a deleted module leaving the list with no REST calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
frontend-templates Ignored Ignored Preview Oct 15, 2026 1:29am UTC

Nothing injected it, but it opened its own MQTT connection and logged every
message had it been. The hot list's Alert type moves to broker-alerts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@stakach
stakach merged commit c2372d1 into develop Oct 15, 2026
5 checks passed
@stakach
stakach deleted the feat/stagehand-trust-mqtt branch October 15, 2026 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant