docs(plans): MES alarm-status API — all 7 open design questions decided
Design review 2026-08-01: (1) MES relevance = dedicated severity band 900-999 (script constants, real IsFlaggedForMES predicate); (2) MESReceiver version DROPPED — CvdReactor is the only implementation, router returns a clean not-supported error elsewhere; (3) Description = Message else AlarmTypeName; (4) enrich the native mirror NOW with an additive AckTime (proto + native_alarm_state + DCL stamping); (5) script names match the endpoints; (6) shared ReactorAlarms on both sides, suffix behavior as planned; (7) existing MES API key, no new roles. Plan is now ready to execute.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# MES Alarm-Status API — Implementation Plan
|
||||
|
||||
**Date:** 2026-06-30
|
||||
**Status:** Draft plan — NOT yet executed. Captures design + task breakdown for review.
|
||||
**Component touchpoints:** Inbound API (#14), Script Analysis (#25), Site Runtime (#3), Template Engine (#1) — plus deployed config (inbound methods + CvdReactor/MESReceiver template scripts).
|
||||
**Status:** Ready to execute — all §6 open questions DECIDED 2026-08-01 (design review with user). Not yet implemented.
|
||||
**Component touchpoints:** Inbound API (#14), Script Analysis (#25), Site Runtime (#3), Template Engine (#1) — plus deployed config (inbound methods + CvdReactor template scripts).
|
||||
|
||||
---
|
||||
|
||||
@@ -12,9 +12,9 @@ Port the legacy **WWSupport / APIServer** MES alarm-status endpoints onto ScadaB
|
||||
|
||||
1. **Update** the existing `SimpleAlarmStatusRequest` inbound method (currently a stub) to do real work.
|
||||
2. **Create** a new `AlarmStatus` inbound method (the full, filtered endpoint).
|
||||
3. Both inbound methods **forward to MES-receiver site scripts** (`SAPID → BTDB machine lookup → Route.To(code).Call(...)`), exactly like `MesMoveIn`.
|
||||
4. The **generic version on the `MESReceiver` template** resolves the machine's alarms by **querying the BTDB `MachineAlarm` table** (the legacy approach).
|
||||
5. The **`CvdReactor` template provides an override version** that reads the **alarms actually defined on the CvdReactor object** (its 7 native alarm-source bindings) directly — no `MachineAlarm` lookup.
|
||||
3. Both inbound methods **forward to site scripts** (`SAPID → BTDB machine lookup → Route.To(code).Call(...)`), exactly like `MesMoveIn`.
|
||||
4. ~~The generic version on the `MESReceiver` template queries the BTDB `MachineAlarm` table.~~ **DROPPED (Q2, 2026-08-01):** no MESReceiver version ships — a config-only answer with no live state was judged not worth having. Machines whose template doesn't implement the scripts get a clean `WasSuccessful=false` "not supported on this machine" error from the inbound router.
|
||||
5. The **`CvdReactor` template provides the (only) implementation**, reading the **alarms actually defined on the CvdReactor object** (its 7 native alarm-source bindings) directly — no `MachineAlarm` lookup anywhere.
|
||||
|
||||
Legacy spec being mirrored: [`docs/former-api-specs/mes/Alarm-API.md`](../former-api-specs/mes/Alarm-API.md).
|
||||
|
||||
@@ -74,10 +74,11 @@ From the site-script API map:
|
||||
```
|
||||
INBOUND (central) ENABLING CODE (repo) SITE TEMPLATE SCRIPTS (deployed config)
|
||||
───────────────── ──────────────────── ───────────────────────────────────────
|
||||
SimpleAlarmStatusRequest ─┐ Alarms script accessor ┌────► MESReceiver.SimpleAlarmStatus (BTDB MachineAlarm)
|
||||
├─ Route.To(code).Call(...) ──┤ MESReceiver.AlarmStatus (BTDB MachineAlarm)
|
||||
AlarmStatus (new) ─┘ (ScriptRuntimeContext + └────► CvdReactor.SimpleAlarmStatus (native sources — OVERRIDE)
|
||||
ScriptCompileSurface) CvdReactor.AlarmStatus (native sources — OVERRIDE)
|
||||
SimpleAlarmStatusRequest ─┐ Alarms script accessor
|
||||
├─ Route.To(code).Call(...) ─────────► CvdReactor.SimpleAlarmStatus (native sources)
|
||||
AlarmStatus (new) ─┘ + AckTime mirror enrichment ──► CvdReactor.AlarmStatus (native sources)
|
||||
(ScriptRuntimeContext +
|
||||
ScriptCompileSurface) (no MESReceiver version — Q2 DECIDED: dropped)
|
||||
```
|
||||
|
||||
### 5.1 Layer A — Inbound API methods (deployed config; central)
|
||||
@@ -110,6 +111,8 @@ try {
|
||||
|
||||
> **Note:** Machine resolution stays on the inbound side (central) because it is environment/SQL-shaped and identical for both endpoints; site scripts receive an already-resolved `MachineCode` plus the alarm filter.
|
||||
|
||||
> **Unsupported machines (Q2 DECIDED):** since only CvdReactor implements the site scripts, `Route.Call` on any other machine fails script-not-found. Both routers catch that case specifically and return `{ WasSuccessful=false, ErrorText = $"Alarm status is not supported on machine '{code}'" }` instead of the raw exception text (verify during impl what exception/message `Route.Call` yields for a missing script so the catch can distinguish it).
|
||||
|
||||
### 5.2 Layer B — Enabling code change: script-facing `Alarms` accessor (repo)
|
||||
|
||||
New read-only accessor on the site script surface so scripts can enumerate the instance's current alarms.
|
||||
@@ -132,9 +135,14 @@ public sealed record ScriptAlarm(
|
||||
string Message, string AlarmTypeName, string Category,
|
||||
string OperatorUser, string OperatorComment,
|
||||
DateTimeOffset? OriginalRaiseTime, DateTimeOffset Timestamp,
|
||||
DateTimeOffset? AckTime, // Q4 DECIDED: real ack timestamp from the enriched mirror
|
||||
string CurrentValue, string LimitValue, bool IsConfiguredPlaceholder);
|
||||
```
|
||||
|
||||
**Ack-timestamp enrichment (Q4 DECIDED 2026-08-01 — enrich the mirror now, not a follow-up):**
|
||||
- Add an additive `AckTime` (`DateTimeOffset?`) to `AlarmStateChanged`, the vendored `AlarmStateUpdate` proto (additive field number, never reuse — manual toggle-build-copy-untoggle regen), and the site `native_alarm_state` persistence so it survives failover.
|
||||
- Semantics: when the underlying source supplies a true ack time (OPC UA A&C ack transitions do), use it; when it doesn't (MxGateway events without one), stamp the observation time of the ack transition at the DCL — accurate to when the system saw the ack, never fabricated. Null while unacked; cleared on re-raise.
|
||||
|
||||
Implementation:
|
||||
- Runtime: `Alarms.CurrentAsync()` Asks the Instance Actor for its alarm snapshot (reuse the existing internal alarm-state map that feeds `DebugViewSnapshot.AlarmStates`; project each `AlarmStateChanged` → `ScriptAlarm`). New internal request/response message (or reuse `DebugSnapshotRequest` and project off `AlarmStates`).
|
||||
- Compile surface: matching stub returning `Task.FromResult(empty)` so design-time compile + Test Run pass.
|
||||
@@ -143,13 +151,9 @@ Implementation:
|
||||
|
||||
### 5.3 Layer C — Site template scripts (deployed config)
|
||||
|
||||
**MESReceiver (generic / "as before" — queries BTDB `MachineAlarm`):** `SimpleAlarmStatus` and `AlarmStatus`.
|
||||
- Use `await Database.Connection("BTDB")` (raw ADO.NET — site Database helper has **no** `QuerySingleAsync`; that's inbound-only) to read the machine's `MachineAlarm` rows (`Name`, `Severity`, `FlaggedForMES`, …) for the resolved `MachineCode`.
|
||||
- Apply legacy filter semantics (Simple = flagged-only; full = `FlaggedOnly/MinSeverity/MaxSeverity/NameFilter`).
|
||||
- Determine live "triggered" state + ack/timestamps and project to `AlarmInfo` (**live-state source = open question §6.2**).
|
||||
- **No `_A`/`_B` side parsing.** This generic version is **whole-machine**, matching the legacy endpoint — it accepts a bare/numeric SAPID and never requires (or errors on) a missing side suffix. Side routing is **CvdReactor-only** (§5.3).
|
||||
**MESReceiver version — DROPPED (Q2 DECIDED 2026-08-01).** With no native alarm sources, MESReceiver has no live "triggered" signal; a configured-catalog-only answer was judged misleading rather than useful. No BTDB `MachineAlarm` read ships anywhere in this feature. Machines without the CvdReactor-style scripts get the router's "not supported on machine" error (§5.1).
|
||||
|
||||
**CvdReactor (override — reads native sources directly, no DB):** `SimpleAlarmStatus` and `AlarmStatus` as **root-level scripts** (so `Route.To(code).Call("SimpleAlarmStatus")` resolves CvdReactor's version for CvdReactor instances — mirrors `MesMoveIn`).
|
||||
**CvdReactor (the only implementation — reads native sources directly, no DB):** `SimpleAlarmStatus` and `AlarmStatus` (Q5 DECIDED: names match the endpoints, template-agnostic contract) as **root-level scripts** (mirrors `MesMoveIn`).
|
||||
|
||||
The override **routes left vs right off the SAPID suffix** — `_A` ⇒ Left, `_B` ⇒ Right — and scopes the returned alarms to that side's native sources plus the shared reactor-wide source. The `_LT` (leak-test) suffix is **ignored** for scoping: it is stripped before reading the side, and both the side's run and leak-test sources are included. Source → side map (the 7 `CvdReactor` native sources):
|
||||
|
||||
@@ -160,6 +164,10 @@ The override **routes left vs right off the SAPID suffix** — `_A` ⇒ Left, `_
|
||||
|
||||
```csharp
|
||||
// CvdReactor.SimpleAlarmStatus (sketch)
|
||||
// Q1 DECIDED: MES relevance = dedicated severity band. Galaxy alarm priorities for
|
||||
// MES-relevant alarms are configured into 900-999; nothing else may use that band.
|
||||
const int MesBandMin = 900;
|
||||
const int MesBandMax = 999;
|
||||
try {
|
||||
var raw = (Parameters["SAPID"] as string) ?? "";
|
||||
var code = Parameters["MachineCode"]?.ToString() ?? "";
|
||||
@@ -180,16 +188,17 @@ try {
|
||||
var infos = alarms
|
||||
.Where(a => a.Active && !a.IsConfiguredPlaceholder) // only triggered
|
||||
.Where(a => InScope(a.NativeSourceCanonicalName)) // _A => Left*, _B => Right*, + ReactorAlarms
|
||||
// SimpleAlarmStatus: flagged-only + acked always included (see §6.1 for FlaggedForMES)
|
||||
// SimpleAlarmStatus semantics: flagged-only (= MES band, Q1) + acked always included
|
||||
.Where(a => a.Severity >= MesBandMin && a.Severity <= MesBandMax)
|
||||
.Select(a => new {
|
||||
Name = a.Name,
|
||||
HierarchicalName = code + "." + a.Name,
|
||||
Description = a.Message, // §6.3
|
||||
IsFlaggedForMES = true, // §6.1
|
||||
Description = string.IsNullOrEmpty(a.Message) ? a.AlarmTypeName : a.Message, // Q3 DECIDED
|
||||
IsFlaggedForMES = a.Severity >= MesBandMin && a.Severity <= MesBandMax, // Q1 DECIDED: real predicate
|
||||
Severity = a.Severity,
|
||||
StatusCode = a.Acknowledged ? "Triggered.Acked" : "Triggered",
|
||||
TriggeredDT = (a.OriginalRaiseTime ?? a.Timestamp),
|
||||
AckDT = (DateTime?)null, // §6.4
|
||||
AckDT = a.AckTime, // Q4 DECIDED: enriched mirror
|
||||
AckComment = a.OperatorComment,
|
||||
}).ToList();
|
||||
return new { WasSuccessful = true, ErrorText = (string)null, Alarms = infos };
|
||||
@@ -197,29 +206,27 @@ try {
|
||||
return new { WasSuccessful = false, ErrorText = "SimpleAlarmStatus failed: " + ex.Message, Alarms = Array.Empty<object>() };
|
||||
}
|
||||
```
|
||||
`CvdReactor.AlarmStatus` is the same — same side parsing + `InScope` filter — but additionally applies the passed `AlarmFilter` (NameFilter/MinSeverity/MaxSeverity/FlaggedOnly/IncludeAcked) over the scoped native list. (When `AlarmStatus` was selected by `Code`/`ZTag`/`MachineID` with no SAPID suffix, `side == null`; in that case return all sources instead of erroring — see §6.6.)
|
||||
`CvdReactor.AlarmStatus` is the same — same side parsing + `InScope` filter, WITHOUT the always-on band filter — but applies the passed `AlarmFilter` (NameFilter/MinSeverity/MaxSeverity/FlaggedOnly/IncludeAcked) over the scoped native list; `FlaggedOnly=true` means the MES-band predicate (Q1). `IsFlaggedForMES` is always reported per-row from the band predicate. (When `AlarmStatus` was selected by `Code`/`ZTag`/`MachineID` with no SAPID suffix, `side == null`; in that case return all sources instead of erroring — Q6b DECIDED.)
|
||||
|
||||
> **Shared `ReactorAlarms` (`Z28061.`) is included on both sides** — reactor-wide faults apply regardless of side. Flip this if MES wants strictly side-local alarms (drop the `StartsWith("Reactor")` clause).
|
||||
> **Shared `ReactorAlarms` (`Z28061.`) is included on both sides — Q6a DECIDED 2026-08-01:** reactor-wide faults apply regardless of which side MES asks about.
|
||||
|
||||
---
|
||||
|
||||
## 6. Key design decisions & OPEN QUESTIONS (resolve before execution)
|
||||
## 6. Key design decisions — ALL DECIDED 2026-08-01 (design review with user)
|
||||
|
||||
These are the Socratic checkpoints — they change script bodies and/or the contract.
|
||||
1. **`IsFlaggedForMES` for native alarms — DECIDED: severity band.** MES relevance is encoded in the alarm severity itself: MES-relevant alarms are configured (in the Galaxy alarm priority) into a **dedicated band 900–999** reserved exclusively for MES-relevant alarms, so it cannot collide with ordinary criticality tuning. Scripts carry `MesBandMin = 900` / `MesBandMax = 999` as named constants; `IsFlaggedForMES = (Severity in band)` is reported honestly per row; `SimpleAlarmStatus` (always flagged-only) and `AlarmStatus` with `FlaggedOnly=true` filter by the band predicate. Since `Severity` is returned verbatim, MES's own `MinSeverity`/`MaxSeverity` filters compose naturally with the band. No new tables, code flags, or allow-lists. **Operational prerequisite:** the Galaxy alarm priorities for MES-relevant CvdReactor alarms must be set into 900–999 before the endpoints are meaningful.
|
||||
|
||||
1. **`IsFlaggedForMES` for native alarms.** The native model has no MES flag (it lived in `MachineAlarm.FlaggedForMES`). Options: (a) treat all native alarms as MES-relevant (`true`); (b) reintroduce an MES allow-list (per native source binding, or a small config/table) the override consults; (c) for `SimpleAlarmStatus` (flagged-only) return all, and only honor `FlaggedOnly` in the full endpoint by cross-referencing `MachineAlarm`. **Recommend (a)** for v1 with (b) as a follow-up, unless MES needs a true flag.
|
||||
2. **MESReceiver version — DECIDED: dropped entirely.** With no native alarm sources there is no live state; a config-only catalog answer was judged not worth shipping. Only CvdReactor implements the scripts; other machines get the router's clean "not supported on machine" error (§5.1). No BTDB `MachineAlarm` dependency remains.
|
||||
|
||||
2. **MESReceiver live-state source.** MESReceiver has no native alarm sources, so after reading `MachineAlarm` config it has no live "InAlarm" source. Options: (a) MESReceiver version returns **configured alarms only** (no live triggered filter) — explicitly a degraded/reference path; (b) MESReceiver version ALSO reads `Alarms.CurrentAsync()` and cross-references `MachineAlarm` by name (works only if the instance happens to mirror native alarms); (c) declare the BTDB-only path returns config and document that live status requires the CvdReactor-style override. **Recommend (c)** — the real live path is CvdReactor; the MESReceiver version demonstrates the MachineAlarm-driven catalog and is the fallback for machine types catalogued in SQL.
|
||||
3. **`Description` mapping — DECIDED:** `Message`, falling back to `AlarmTypeName` when `Message` is empty.
|
||||
|
||||
3. **`Description` mapping.** Legacy `Description` came from the MXAccess `DescAttrName` tag. `AlarmStateChanged` has no dedicated description; closest is `Message` (per-band operator text) / `AlarmTypeName` / `Category`. **Recommend `Message`, fall back to `AlarmTypeName`.** Confirm acceptable.
|
||||
4. **`AckDT` mapping — DECIDED: enrich the native mirror now.** Additive `AckTime` on `AlarmStateChanged` + vendored proto + `native_alarm_state` (survives failover). True source ack time where available (OPC UA A&C); DCL observation time of the ack transition where the source lacks one (MxGateway); null while unacked; cleared on re-raise. See §5.2.
|
||||
|
||||
4. **`AckDT` mapping.** No explicit ack-timestamp in `AlarmStateChanged` (`Timestamp` = last change, `OriginalRaiseTime` = raise). For acked alarms we can't precisely fill `AckDT`. Options: (a) leave `null`; (b) use `Timestamp` when `Acknowledged` (approximate); (c) enrich the native mirror to carry an ack timestamp (larger change). **Recommend (a)** for v1, (c) as a follow-up if MES depends on it.
|
||||
5. **Script naming — DECIDED: `SimpleAlarmStatus` / `AlarmStatus`** (match the endpoint names; template-agnostic contract any future machine template can implement). With the MESReceiver version dropped there is no parallel definition, so no override-resolution concern remains.
|
||||
|
||||
5. **Script naming / override resolution.** Keep script names **identical** across both templates (`SimpleAlarmStatus`, `AlarmStatus`) so the inbound method is template-agnostic (`Call("AlarmStatus")`), and CvdReactor's root-level definition is what `Route.Call` resolves for CvdReactor instances. (Alternative: `Mes`-prefixed CvdReactor scripts like `MesMoveIn`.) **Recommend identical names**; confirm `Route.Call` resolves a CvdReactor root script over any composed-module script of the same name (verify during impl — the MoveIn precedent says yes).
|
||||
6. **Side scoping — DECIDED (all parts).** CvdReactor-only: `_A` ⇒ Left, `_B` ⇒ Right; `_LT` stripped before reading the side (leak-test sources still included). (a) shared `ReactorAlarms` (`Z28061.`) **included on both sides** — reactor-wide faults apply regardless of side. (b) missing suffix: `SimpleAlarmStatus` **errors** on a SAPID without `_A`/`_B` (matches `MesMoveIn`); `AlarmStatus` selected by `Code`/`ZTag`/`MachineID` (no SAPID) **returns all sources**; a SAPID selector without a suffix errors.
|
||||
|
||||
6. **Side scoping — DECIDED, CvdReactor-only.** Only the **CvdReactor** override routes off the SAPID suffix: `_A` ⇒ Left, `_B` ⇒ Right; `_LT` is ignored (stripped before reading the side; leak-test sources still included). Mirrors `MesMoveIn`. The generic **MESReceiver** version and the inbound method do **not** parse or require the suffix — they stay whole-machine (legacy). Two residual sub-choices remain: (a) **shared `ReactorAlarms` (`Z28061.`) included on both sides** (current plan) vs strictly side-local — confirm; (b) **missing `_A`/`_B` suffix** — the **CvdReactor** `SimpleAlarmStatus` **errors** (matches `MesMoveIn`); the **CvdReactor** `AlarmStatus` selected by `Code`/`ZTag`/`MachineID` (no SAPID) **returns all sources** rather than erroring; the MESReceiver version never errors on a missing suffix — confirm acceptable.
|
||||
|
||||
7. **New method roles / auth.** `AlarmStatus` is a new inbound `ApiMethod` (`X-API-Key`); creating it requires `Roles.Designer`. No new global roles. Confirm the API key in use is authorized.
|
||||
7. **Roles / auth — DECIDED:** no new roles; create `AlarmStatus` as Designer via CLI; authorize the **existing MES API key** (the one already calling `MesMoveIn`/`MesMoveOut`) for both alarm endpoints — one key per external system.
|
||||
|
||||
---
|
||||
|
||||
@@ -227,26 +234,26 @@ These are the Socratic checkpoints — they change script bodies and/or the cont
|
||||
|
||||
> Two artifact classes: **[repo]** = source/tests/docs committed to git; **[deployed]** = inbound methods / template scripts pushed to the cluster via CLI/UI (not in repo). The user said "don't execute yet" — this is the ordered plan only.
|
||||
|
||||
**Phase 1 — Enabling `Alarms` script API [repo]**
|
||||
1. Add `AlarmsAccessor` + `ScriptAlarm` to the runtime context (`ScriptRuntimeContext`) — local Ask to the Instance Actor; project `AlarmStateChanged` → `ScriptAlarm`. Add internal request/response message if not reusing `DebugSnapshotRequest`.
|
||||
2. Mirror the stub on `ScriptCompileSurface` (and confirm `TriggerCompileSurface` not needed — trigger expressions don't read alarms).
|
||||
3. Confirm/extend `ScriptTrustPolicy` allow-list so `Alarms` is permitted; no new forbidden APIs.
|
||||
4. Unit tests: runtime accessor projection (active/acked/severity/timestamps), compile-surface compiles a representative `Alarms.CurrentAsync()` script, trust-policy accepts it.
|
||||
5. Doc: update `docs/requirements/Component-SiteRuntime.md` (+ Script Analysis #25 surface list) to document the `Alarms` accessor; note it in `Component-InboundAPI.md` routing examples.
|
||||
**Phase 1 — Enabling `Alarms` script API + AckTime mirror enrichment [repo]**
|
||||
1. **AckTime enrichment (§6.4):** additive `AckTime` on `AlarmStateChanged`, the vendored `AlarmStateUpdate` proto (manual regen), `native_alarm_state` persistence, and the DCL ack-transition stamping (source ack time where supplied, else observation time).
|
||||
2. Add `AlarmsAccessor` + `ScriptAlarm` to the runtime context (`ScriptRuntimeContext`) — local Ask to the Instance Actor; project `AlarmStateChanged` → `ScriptAlarm` (incl. `AckTime`). Add internal request/response message if not reusing `DebugSnapshotRequest`.
|
||||
3. Mirror the stub on `ScriptCompileSurface` (and confirm `TriggerCompileSurface` not needed — trigger expressions don't read alarms).
|
||||
4. Confirm/extend `ScriptTrustPolicy` allow-list so `Alarms` is permitted; no new forbidden APIs.
|
||||
5. Unit tests: runtime accessor projection (active/acked/severity/timestamps/AckTime), AckTime stamping + failover persistence, compile-surface compiles a representative `Alarms.CurrentAsync()` script, trust-policy accepts it.
|
||||
6. Doc: update `Component-SiteRuntime.md` + `Component-DataConnectionLayer.md` (native-mirror AckTime) + Script Analysis #25 surface list; note the accessor in `Component-InboundAPI.md` routing examples.
|
||||
|
||||
**Phase 2 — Inbound methods [deployed] + doc [repo]**
|
||||
6. Update `SimpleAlarmStatusRequest` (id 9) body to the §5.1 router (validate via design page first to avoid the stale-handler trap — see memory `inbound-noncompiling-update-keeps-old-handler`).
|
||||
7. Create `AlarmStatus` method (params/return/script per §5.1).
|
||||
8. Doc the two endpoints in `docs/requirements/Component-InboundAPI.md` (or a dedicated MES-integration note) cross-referencing the legacy spec.
|
||||
7. Update `SimpleAlarmStatusRequest` (id 9) body to the §5.1 router incl. the not-supported-machine catch (validate via design page first to avoid the stale-handler trap — see memory `inbound-noncompiling-update-keeps-old-handler`).
|
||||
8. Create `AlarmStatus` method (params/return/script per §5.1); authorize the existing MES API key for both methods (§6.7).
|
||||
9. Doc the two endpoints in `docs/requirements/Component-InboundAPI.md` (or a dedicated MES-integration note) cross-referencing the legacy spec.
|
||||
|
||||
**Phase 3 — Site template scripts [deployed]**
|
||||
9. Add `SimpleAlarmStatus` + `AlarmStatus` to **MESReceiver** (BTDB `MachineAlarm` via `Database.Connection("BTDB")`), per §6.2 decision.
|
||||
10. Add override `SimpleAlarmStatus` + `AlarmStatus` to **CvdReactor** (native sources via `Alarms.CurrentAsync()`), per §5.3.
|
||||
11. `template validate` both templates (script compilation gate) before redeploy; redeploy affected instances.
|
||||
**Phase 3 — Site template scripts [deployed]** *(MESReceiver task removed — §6.2 decided dropped)*
|
||||
10. Add `SimpleAlarmStatus` + `AlarmStatus` to **CvdReactor** (native sources via `Alarms.CurrentAsync()`, MES band constants), per §5.3.
|
||||
11. `template validate` (script compilation gate) before redeploy; redeploy affected instances.
|
||||
|
||||
**Phase 4 — Verify**
|
||||
12. Build affected projects + run targeted tests (per memory `targeted-tests-not-full-suite`).
|
||||
13. Live smoke against a real reactor instance (see §8) — both endpoints, success + machine-not-found + filtered.
|
||||
13. Live smoke against a real reactor instance (see §8) — both endpoints, success + machine-not-found + not-supported-machine + filtered. Requires the Galaxy MES-band priorities (§6.1) to be set for a meaningful flagged-only result.
|
||||
|
||||
---
|
||||
|
||||
@@ -261,10 +268,10 @@ These are the Socratic checkpoints — they change script bodies and/or the cont
|
||||
|
||||
## 9. Out of scope / follow-ups
|
||||
|
||||
- True `IsFlaggedForMES` for native alarms (per-source MES allow-list) — §6.1 option (b).
|
||||
- Precise `AckDT` (enrich native mirror with an ack timestamp) — §6.4 option (c).
|
||||
- ~~True `IsFlaggedForMES` allow-list~~ — resolved by the §6.1 severity-band decision (no follow-up needed).
|
||||
- ~~Precise `AckDT` follow-up~~ — pulled INTO scope by §6.4 (mirror enriched now).
|
||||
- A live/aggregated central alarm store or stream (the M7 follow-up) — these endpoints stay pull-based, per-instance, like the Alarm Summary page.
|
||||
- MESReceiver live-state path if §6.2 (c) is chosen and MES later needs live status from non-native machines.
|
||||
- Alarm-status support for non-CvdReactor machine types (any future template just implements `SimpleAlarmStatus`/`AlarmStatus` root scripts against the same contract).
|
||||
|
||||
---
|
||||
|
||||
@@ -272,13 +279,14 @@ These are the Socratic checkpoints — they change script bodies and/or the cont
|
||||
|
||||
| Artifact | Type | Change |
|
||||
|---|---|---|
|
||||
| `ScriptRuntimeContext` | [repo] | New `Alarms` accessor + `ScriptAlarm`; local alarm-snapshot Ask |
|
||||
| `AlarmStateChanged` + vendored `AlarmStateUpdate` proto + `native_alarm_state` + DCL stamping | [repo] | Additive `AckTime` enrichment (§6.4) |
|
||||
| `ScriptRuntimeContext` | [repo] | New `Alarms` accessor + `ScriptAlarm` (incl. `AckTime`); local alarm-snapshot Ask |
|
||||
| `ScriptCompileSurface` | [repo] | Mirror `Alarms` stub |
|
||||
| `ScriptTrustPolicy` (#25) | [repo] | Allow `Alarms` member (verify) |
|
||||
| Internal alarm-snapshot message (or reuse `DebugSnapshotRequest`) | [repo] | Additive |
|
||||
| Site Runtime + Script Analysis + Inbound API docs | [repo] | Document `Alarms` accessor + endpoints |
|
||||
| Site Runtime + DCL + Script Analysis + Inbound API docs | [repo] | Document `Alarms` accessor, `AckTime`, endpoints |
|
||||
| Unit tests (SiteRuntime / ScriptAnalysis / InboundAPI) | [repo] | New |
|
||||
| `SimpleAlarmStatusRequest` (id 9) | [deployed] | Stub → real router |
|
||||
| `AlarmStatus` (new) | [deployed] | New inbound method |
|
||||
| `MESReceiver.SimpleAlarmStatus` / `.AlarmStatus` | [deployed] | New BTDB-driven scripts |
|
||||
| `CvdReactor.SimpleAlarmStatus` / `.AlarmStatus` | [deployed] | New native-source override scripts |
|
||||
| `SimpleAlarmStatusRequest` (id 9) | [deployed] | Stub → real router (+ not-supported catch) |
|
||||
| `AlarmStatus` (new) | [deployed] | New inbound method, existing MES key authorized |
|
||||
| `CvdReactor.SimpleAlarmStatus` / `.AlarmStatus` | [deployed] | New native-source scripts (MES band 900–999) |
|
||||
| Galaxy alarm priorities | [external] | MES-relevant CvdReactor alarms configured into 900–999 (§6.1 prerequisite) |
|
||||
|
||||
Reference in New Issue
Block a user