docs(m3): document Script Analysis component (#25); reconcile consumer specs + README/CLAUDE component list
This commit is contained in:
@@ -63,7 +63,7 @@ Related repos cloned as sibling directories under `~/Desktop/` — referenced fo
|
||||
- Commit related changes together with a descriptive message summarizing the design decision and the implementation slice.
|
||||
- After non-trivial code changes, build (`dotnet build ZB.MOM.WW.ScadaBridge.slnx`) and run relevant tests before declaring done; for cluster-runtime changes, rebuild the image with `bash docker/deploy.sh`.
|
||||
|
||||
## Current Component List (24 components)
|
||||
## Current Component List (25 components)
|
||||
|
||||
1. Template Engine — Template modeling, inheritance, composition, validation, flattening, diffs.
|
||||
2. Deployment Manager — Central-side deployment pipeline, system-wide artifact deployment, instance lifecycle.
|
||||
@@ -89,6 +89,7 @@ Related repos cloned as sibling directories under `~/Desktop/` — referenced fo
|
||||
22. Site Call Audit — Central component auditing site cached calls (`CachedCall`/`CachedWrite`); `SiteCalls` audit table, telemetry ingest, reconciliation, KPIs, central→site Retry/Discard relay; sites remain the source of truth.
|
||||
23. Audit Log — Central append-only AuditLog table spanning every script-trust-boundary action (outbound API sync+cached, outbound DB sync+cached, notifications, inbound API). Site SQLite hot-path + gRPC telemetry + reconciliation; combined telemetry with Site Call Audit; central direct-write for Notification Outbox dispatch + Inbound API; monthly partitioning, 365-day retention.
|
||||
24. Transport — File-based, encrypted bundle export/import via Central UI. Templates, system artifacts, central-only configuration. Per-conflict resolution. Correlated audit via `BundleImportId`. No site involvement.
|
||||
25. Script Analysis — Shared authoritative script-trust analyzer: unified forbidden-API deny-list (`ScriptTrustPolicy`), fused semantic+syntactic validator (`ScriptTrustValidator`), Roslyn compile wrapper (`RoslynScriptCompiler`), and compile-only globals stubs (`ScriptCompileSurface`/`TriggerCompileSurface`); consumed by Template Engine, Site Runtime, Inbound API, and Central UI.
|
||||
|
||||
## Key Design Decisions (for context across sessions)
|
||||
|
||||
@@ -211,7 +212,7 @@ Related repos cloned as sibling directories under `~/Desktop/` — referenced fo
|
||||
### Akka.NET Conventions
|
||||
- Tell for hot-path internal communication; Ask reserved for system boundaries.
|
||||
- ClusterClient for cross-cluster communication; ClusterClientReceptionist for service discovery across cluster boundaries.
|
||||
- Script trust model: forbidden APIs (System.IO, Process, Threading, Reflection, raw network).
|
||||
- Script trust model: forbidden APIs (System.IO, Process, Threading, Reflection, raw network). The trust boundary is centralized in the Script Analysis component (#25) — `ScriptTrustPolicy` is the single source of truth; all four call sites (Template Engine, Site Runtime, Inbound API, Central UI) delegate to `ScriptTrustValidator`. The design-time deploy gate in Template Engine is authoritative (real semantic compile), not advisory.
|
||||
- Application-level correlation IDs on all request/response messages.
|
||||
|
||||
## Tool Usage
|
||||
|
||||
@@ -100,6 +100,7 @@ Both stacks share the infrastructure services in [`infra/`](infra/) (MS SQL, LDA
|
||||
| 22 | Site Call Audit | [docs/requirements/Component-SiteCallAudit.md](docs/requirements/Component-SiteCallAudit.md) | Central component auditing site cached calls (`ExternalSystem.CachedCall`/`Database.CachedWrite`) into the `SiteCalls` audit table, with `SiteCallAuditActor` singleton, telemetry ingest, periodic reconciliation, point-in-time KPIs, daily purge, and central→site Retry/Discard relay for parked calls. |
|
||||
| 23 | Audit Log | [docs/requirements/Component-AuditLog.md](docs/requirements/Component-AuditLog.md) | New central append-only AuditLog spanning every script-trust-boundary action (outbound API sync+cached, outbound DB sync+cached, notifications, inbound API). Site-local SQLite hot-path append + gRPC telemetry + central reconciliation; combined telemetry packet with Site Call Audit; central direct-write for Notification Outbox dispatch + Inbound API middleware; monthly partitioning, 365-day default retention. |
|
||||
| 24 | Transport | [docs/requirements/Component-Transport.md](docs/requirements/Component-Transport.md) | Bundle export/import for templates, shared scripts, external systems, central-only artifacts. AES-256-GCM encryption; per-conflict resolution on import; correlated audit trail. |
|
||||
| 25 | Script Analysis | [docs/requirements/Component-ScriptAnalysis.md](docs/requirements/Component-ScriptAnalysis.md) | Shared authoritative script-trust analyzer: unified forbidden-API deny-list (`ScriptTrustPolicy`), fused semantic+syntactic validator (`ScriptTrustValidator`), Roslyn compile wrapper (`RoslynScriptCompiler`), and compile-only globals stubs (`ScriptCompileSurface`/`TriggerCompileSurface`); consumed by Template Engine, Site Runtime, Inbound API, and Central UI. |
|
||||
|
||||
**Shared UI sub-component** (not a top-level component): [TreeView](docs/requirements/Component-TreeView.md) — reusable hierarchical tree/grid Blazor component used by the Central UI (#9) for the templates folder hierarchy, data-connection browse, and tag pickers.
|
||||
|
||||
|
||||
@@ -197,12 +197,17 @@ Inbound API scripts **cannot** call shared scripts directly — shared scripts a
|
||||
> **No direct database access.** Inbound API scripts are not given a raw database
|
||||
> client. Handing a script a raw `SqlConnection` is in direct tension with the
|
||||
> ScadaBridge script trust model (scripts are forbidden `System.IO`, `Process`,
|
||||
> `Threading`, `Reflection`, and raw network access; `ForbiddenApiChecker`
|
||||
> statically enforces this). Scripts interact with the system only through the
|
||||
> curated `Route` and `Parameters` surfaces above. If a method needs data from
|
||||
> the configuration or machine-data databases, that access belongs behind a
|
||||
> dedicated, scoped helper — not a general-purpose connection — and would be
|
||||
> added here as an explicit design change.
|
||||
> `Threading`, `Reflection`, and raw network access). The `ForbiddenApiChecker`
|
||||
> statically enforces this by delegating to the shared `ScriptAnalysis`
|
||||
> `ScriptTrustValidator` (component #25), which is the single authoritative
|
||||
> source of truth for the forbidden-API policy. The unified policy permits
|
||||
> `System.Diagnostics.Stopwatch`/`Debug` while retaining the `Process`-only ban,
|
||||
> and adds reflection-gateway member and `dynamic`/`Activator` hardening.
|
||||
> This is defence-in-depth static enforcement, not a true runtime sandbox. Scripts
|
||||
> interact with the system only through the curated `Route` and `Parameters`
|
||||
> surfaces above. If a method needs data from the configuration or machine-data
|
||||
> databases, that access belongs behind a dedicated, scoped helper — not a
|
||||
> general-purpose connection — and would be added here as an explicit design change.
|
||||
|
||||
### Routing Behavior
|
||||
- The `Route.To()` helper resolves the instance's site assignment from the configuration database and routes the request to the correct site cluster via the Communication Layer.
|
||||
@@ -232,6 +237,7 @@ Inbound API scripts **cannot** call shared scripts directly — shared scripts a
|
||||
- **Communication Layer**: Routes requests to sites when method implementations need site data.
|
||||
- **Security & Auth**: API key validation (separate from LDAP/AD — API uses key-based auth).
|
||||
- **Configuration Database (via IAuditService)**: All API key and method definition changes are audit logged.
|
||||
- **Script Analysis (#25)**: `ForbiddenApiChecker` delegates to `ScriptTrustValidator.FindViolations` for the authoritative forbidden-API verdict during script compilation and validation.
|
||||
- **Audit Log (#23)**: Every inbound API request emits an `ApiInbound.Completed` row via `ICentralAuditWriter` from request middleware (non-blocking for the HTTP response). Request and response bodies are captured in full up to `AuditLog:InboundMaxBytes` (default 1 MiB) per the Audit Log Payload Capture Policy; redaction (headers + per-target body redactors) still applies before persistence.
|
||||
- **Cluster Infrastructure**: API is hosted on the active central node and fails over with it.
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
# Component: Script Analysis
|
||||
|
||||
## Purpose
|
||||
|
||||
The Script Analysis component is the single authoritative source of truth for the ScadaBridge script trust model. It provides a unified forbidden-API deny-list, a fused semantic and syntactic trust validator, a Roslyn compile wrapper, and compile-only globals stubs used by the design-time deploy gate. All four call sites that enforce the script trust boundary — Template Engine, Site Runtime, Inbound API, and Central UI — delegate to this component rather than maintaining their own divergent implementations.
|
||||
|
||||
## Location
|
||||
|
||||
`src/ZB.MOM.WW.ScadaBridge.ScriptAnalysis/`
|
||||
|
||||
Referenced by: Template Engine, Site Runtime, Inbound API, Central UI.
|
||||
|
||||
## Responsibilities
|
||||
|
||||
- Define the canonical forbidden-API deny-list (`ScriptTrustPolicy`) as the single source of truth for all trust enforcement decisions across the system.
|
||||
- Provide an authoritative forbidden-API verdict (`ScriptTrustValidator.FindViolations`) that fuses semantic symbol resolution with syntactic reflection-gateway hardening.
|
||||
- Wrap Roslyn `CSharpScript` compilation (`RoslynScriptCompiler`) so callers share one implementation of compile + diagnostics extraction.
|
||||
- Provide compile-only globals stubs (`ScriptCompileSurface`, `TriggerCompileSurface`) that mirror the real execution-time globals member-for-member, allowing the design-time deploy gate to do a real type-checking compile without depending on the execution-time projects.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
### REQ-SA-1: Trust Policy (`ScriptTrustPolicy`)
|
||||
|
||||
`ScriptTrustPolicy` is a static class (or record) that publishes the complete, authoritative forbidden-API policy used at every call site.
|
||||
|
||||
#### Forbidden scopes
|
||||
|
||||
The following namespace/type prefixes are forbidden in all scripts:
|
||||
|
||||
| Scope | Rationale |
|
||||
|-------|-----------|
|
||||
| `System.IO` | File system access — forbidden entirely |
|
||||
| `System.Diagnostics.Process` | Process spawning — forbidden; `Stopwatch`, `Debug`, `Activity`, and other `System.Diagnostics` types are **allowed** |
|
||||
| `System.Threading` | Raw thread manipulation — forbidden, with the exceptions below |
|
||||
| `System.Reflection` | Reflection — forbidden entirely |
|
||||
| `System.Net` | Raw network access — forbidden entirely (scripts must use `ExternalSystem.Call`) |
|
||||
| `System.Runtime.InteropServices` | Native interop — forbidden entirely |
|
||||
| `Microsoft.Win32` | Win32 API access — forbidden entirely |
|
||||
|
||||
#### Allowed exceptions within forbidden scopes
|
||||
|
||||
The following types are explicitly allowed despite falling within a forbidden namespace:
|
||||
|
||||
- `System.Threading.Tasks` (and all subtypes) — async/await support
|
||||
- `System.Threading.CancellationToken` — cooperative cancellation
|
||||
- `System.Threading.CancellationTokenSource` — cooperative cancellation
|
||||
|
||||
The scoping rationale: `System.Diagnostics.Process` is the dangerous type (spawns processes); `Stopwatch`, `Debug`, and `Activity` are harmless diagnostic utilities. Forbidding the whole `System.Diagnostics` namespace, as some earlier call sites did, was overly broad.
|
||||
|
||||
#### Reflection-gateway members
|
||||
|
||||
The following member names are blocked regardless of the receiver type, to prevent reflection-based bypasses such as `typeof(x).Assembly.GetType("System.IO.File")`:
|
||||
|
||||
`GetType`, `GetTypeInfo`, `Assembly`, `Module`, `CreateInstance`, `InvokeMember`, `GetMethod`, `GetMethods`, `GetConstructor`, `GetConstructors`, `GetField`, `GetFields`, `GetProperty`, `GetProperties`, `GetMember`, `GetMembers`, `GetRuntimeMethod`, `GetRuntimeMethods`, `MethodHandle`, `TypeHandle`.
|
||||
|
||||
#### Forbidden identifiers
|
||||
|
||||
The identifiers `dynamic` and `Activator` are forbidden at any scope, as they provide type-system escape hatches equivalent to reflection.
|
||||
|
||||
#### Default references and imports
|
||||
|
||||
`ScriptTrustPolicy` also publishes `DefaultReferences` (the canonical set of trusted-platform `MetadataReference` entries used when constructing the Roslyn script compilation context) and `DefaultImports` (the default `using` directives injected into every script). These are consumed by `RoslynScriptCompiler` and by the compile-only surfaces below.
|
||||
|
||||
---
|
||||
|
||||
### REQ-SA-2: Trust Validator (`ScriptTrustValidator`)
|
||||
|
||||
`ScriptTrustValidator.FindViolations(string code, IEnumerable<MetadataReference>? extraReferences = null)` is the **authoritative forbidden-API gate**. It returns a list of violation messages; an empty list means the script is clean.
|
||||
|
||||
#### Two-pass design
|
||||
|
||||
**Pass 1 — semantic symbol resolution (adapted from Site Runtime)**
|
||||
|
||||
- Builds a Roslyn compilation using the full trusted-platform reference set from `ScriptTrustPolicy.DefaultReferences` (plus any `extraReferences`).
|
||||
- For each identifier in the syntax tree, resolves the underlying symbol to its fully qualified containing namespace and type name.
|
||||
- Flags any symbol whose containing namespace or type matches a forbidden scope in `ScriptTrustPolicy.ForbiddenScopes`, taking `AllowedExceptions` into account.
|
||||
- Correctly handles aliases (`using X = System.IO.File`), `using static`, and `global::` prefixes — the resolved symbol is checked, not the spelling.
|
||||
- Because the full reference set is loaded, this pass also catches a forbidden type accessed inside an otherwise-allowed namespace (e.g., bare `Process` after `using System.Diagnostics;`).
|
||||
|
||||
**Pass 2 — syntactic reflection-gateway and identifier hardening (adapted from Inbound API)**
|
||||
|
||||
- Walks the syntax tree for member-access expressions and simple name references.
|
||||
- Flags any member name found in `ScriptTrustPolicy.ReflectionGatewayMembers`, regardless of receiver type.
|
||||
- Flags any identifier token found in `ScriptTrustPolicy.ForbiddenIdentifiers` (`dynamic`, `Activator`).
|
||||
|
||||
Violations from both passes are merged and deduplicated before being returned.
|
||||
|
||||
#### Design notes
|
||||
|
||||
- `FindViolations` needs no globals type; it operates solely on the script text and the trusted-platform reference set.
|
||||
- The function is stateless and thread-safe — callers share a single instance or call it as a static method.
|
||||
- A violation does not abort compilation; callers may choose to report violations and continue, or treat any violation as a hard reject.
|
||||
|
||||
---
|
||||
|
||||
### REQ-SA-3: Roslyn Compile Wrapper (`RoslynScriptCompiler`)
|
||||
|
||||
`RoslynScriptCompiler` wraps `CSharpScript` to give callers a single implementation of compile + diagnostics extraction.
|
||||
|
||||
#### `Compile(string code, Type? globalsType = null, IEnumerable<MetadataReference>? extraReferences = null, IEnumerable<string>? extraImports = null)`
|
||||
|
||||
- Creates a `CSharpScript` with the given code, `globalsType`, references (defaults from `ScriptTrustPolicy.DefaultReferences` plus `extraReferences`), and imports (defaults from `ScriptTrustPolicy.DefaultImports` plus `extraImports`).
|
||||
- Calls `.Compile()` and returns the resulting `Diagnostic[]` filtered to errors and warnings.
|
||||
- Each caller passes its own `globalsType` — `ScriptCompileSurface` for the design-time deploy gate, the real `ScriptGlobals` for Site Runtime execution, `null` for pure syntax checks.
|
||||
|
||||
#### `ParseDiagnostics(string code)`
|
||||
|
||||
- Parses the script text using Roslyn's `CSharpSyntaxTree.ParseText` and returns syntax-level diagnostics (errors and warnings).
|
||||
- No compilation is performed — useful for fast syntax checks where no globals type is available.
|
||||
|
||||
---
|
||||
|
||||
### REQ-SA-4: Compile-Only Globals Stubs
|
||||
|
||||
The deploy gate in Template Engine must do a real type-checking compile (to catch undefined-symbol and type errors) but cannot depend on the execution-time projects (Site Runtime, Inbound API) that own the real globals. Two compile-only stubs solve this:
|
||||
|
||||
#### `ScriptCompileSurface`
|
||||
|
||||
Mirrors `ScriptGlobals` member-for-member (same public property names, same return types, same method signatures) but with no implementation bodies. All properties return `default` and all methods return `default` or `Task.CompletedTask`. Depends only on `Commons.Types` — no Akka.NET, no external system clients.
|
||||
|
||||
Used by the Template Engine deploy gate:
|
||||
```csharp
|
||||
var errors = RoslynScriptCompiler.Compile(code, typeof(ScriptCompileSurface));
|
||||
```
|
||||
This allows the compile to bind `Attributes["name"]`, `Notify.To("x").Send(...)`, `ExternalSystem.Call(...)`, and similar API calls against real types, catching undefined-symbol and type-mismatch errors before deployment.
|
||||
|
||||
#### `TriggerCompileSurface`
|
||||
|
||||
Mirrors `TriggerExpressionGlobals` in the same way. Used by `ValidationService.CheckExpressionSyntax` in the Template Engine for conditional and expression trigger validation.
|
||||
|
||||
#### Parity guard
|
||||
|
||||
A reflection-based parity test in `SiteRuntime.Tests` compares the public member names on `ScriptCompileSurface` against `ScriptGlobals` (and `TriggerCompileSurface` against `TriggerExpressionGlobals`). Any drift between the stub and the real globals causes this test to fail, ensuring the stubs cannot silently fall out of sync.
|
||||
|
||||
---
|
||||
|
||||
### REQ-SA-5: Consumer Delegation
|
||||
|
||||
All four call sites that previously maintained their own script trust enforcement now delegate to this component. The key behavioral changes per consumer:
|
||||
|
||||
| Consumer | Before | After |
|
||||
|----------|--------|-------|
|
||||
| **Template Engine** `ScriptCompiler.TryCompile` | Substring scan + brace-balance (advisory, bypassable) | `FindViolations` + real `Compile` against `ScriptCompileSurface` — authoritative gate |
|
||||
| **Template Engine** `ValidationService.CheckExpressionSyntax` | Regex / brace scan | `FindViolations` + `Compile` against `TriggerCompileSurface` |
|
||||
| **Site Runtime** `ScriptCompilationService.ValidateTrustModel` | Semantic resolver, no reflection-gateway hardening | Delegates to `FindViolations`; retains `CSharpScript.Compile` against real `ScriptGlobals` for execution |
|
||||
| **Inbound API** `ForbiddenApiChecker.FindViolations` | Syntactic walker, forbade all `System.Diagnostics` | Thin shim delegating to `ScriptTrustValidator.FindViolations`; `System.Diagnostics` loosened to `.Process`-only |
|
||||
| **Central UI** `ScriptAnalysisService` | Semantic + full compile, lenient threading | Delegates forbidden-API verdict and sources editor-marker deny-list from `ScriptTrustPolicy`; retains Test-Run execution host |
|
||||
|
||||
The static enforcement is **defence-in-depth**, not a true runtime sandbox. Scripts execute in-process; the denied API list prevents obvious escapes at compile time but does not provide the isolation guarantees of an out-of-process sandbox or a restricted `AssemblyLoadContext`. This caveat applies to all consumers.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Commons**: Shared types referenced by `ScriptCompileSurface` and `TriggerCompileSurface` (e.g., `DataType`, attribute access types).
|
||||
- **Microsoft.CodeAnalysis.CSharp.Scripting**: Roslyn scripting APIs used by `RoslynScriptCompiler` and `ScriptTrustValidator`.
|
||||
- **Microsoft.CodeAnalysis.CSharp.Workspaces**: Roslyn workspace/syntax APIs used by `ScriptTrustValidator`.
|
||||
|
||||
No dependency on Akka.NET, ASP.NET Core, Entity Framework, or any other ScadaBridge component above Commons.
|
||||
|
||||
## Interactions
|
||||
|
||||
- **Template Engine (#1)**: Consumes `ScriptTrustValidator.FindViolations`, `RoslynScriptCompiler.Compile`, `ScriptCompileSurface`, and `TriggerCompileSurface` in the design-time deploy gate (`ScriptCompiler.TryCompile`) and expression syntax validator (`ValidationService.CheckExpressionSyntax`).
|
||||
- **Site Runtime (#3)**: `ScriptCompilationService.ValidateTrustModel` delegates the trust verdict to `ScriptTrustValidator.FindViolations`; retains its own `CSharpScript.Compile` against the real `ScriptGlobals` for execution-time compilation.
|
||||
- **Inbound API (#14)**: `ForbiddenApiChecker.FindViolations` is a thin shim over `ScriptTrustValidator.FindViolations`.
|
||||
- **Central UI (#9)**: `ScriptAnalysisService` delegates the run-gate forbidden-API verdict and sources the editor-marker deny-list from `ScriptTrustPolicy`; retains the Test-Run execution host (`SandboxScriptHost`).
|
||||
@@ -392,12 +392,12 @@ Available to all Script Execution Actors and Alarm Execution Actors:
|
||||
|
||||
Scripts execute **in-process** with constrained access. The following restrictions are enforced at compilation and runtime:
|
||||
|
||||
- **Allowed**: Access to the Script Runtime API (GetAttribute, SetAttribute, CallScript, CallShared, ExternalSystem, Notify, Database, Tracking), standard C# language features, basic .NET types (collections, string manipulation, math, date/time).
|
||||
- **Forbidden**: File system access (`System.IO`), process spawning (`System.Diagnostics.Process`), threading (`System.Threading` — except async/await), reflection (`System.Reflection`), raw network access (`System.Net.Sockets`, `System.Net.Http` — must use `ExternalSystem.Call`), assembly loading, unsafe code.
|
||||
- **Allowed**: Access to the Script Runtime API (GetAttribute, SetAttribute, CallScript, CallShared, ExternalSystem, Notify, Database, Tracking), standard C# language features, basic .NET types (collections, string manipulation, math, date/time). `System.Diagnostics.Stopwatch`, `Debug`, and `Activity` are permitted.
|
||||
- **Forbidden**: File system access (`System.IO`), process spawning (`System.Diagnostics.Process`), threading (`System.Threading` — except `Tasks`, `CancellationToken`, and `CancellationTokenSource`), reflection (`System.Reflection`), all raw network access (`System.Net` — must use `ExternalSystem.Call`), native interop (`System.Runtime.InteropServices`, `Microsoft.Win32`), assembly loading, unsafe code, `dynamic`, `Activator`.
|
||||
- **Execution timeout**: Configurable per-script maximum execution time. Exceeding the timeout cancels the script and logs an error.
|
||||
- **Memory**: Scripts share the host process memory. No per-script memory limit, but the execution timeout prevents runaway allocations.
|
||||
|
||||
These constraints are enforced by restricting the set of assemblies and namespaces available to the script compilation context.
|
||||
The forbidden-API policy is defined authoritatively in `ScriptTrustPolicy` (Script Analysis component, #25). `ScriptCompilationService.ValidateTrustModel` delegates to `ScriptTrustValidator.FindViolations` for the trust verdict; the Site Runtime also performs a `CSharpScript.Compile` against the real `ScriptGlobals` for execution. This is defence-in-depth static enforcement, not a true runtime sandbox.
|
||||
|
||||
### Script Trust Boundary Auditing
|
||||
|
||||
@@ -466,6 +466,7 @@ Per Akka.NET best practices, internal actor communication uses **Tell** (fire-an
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Script Analysis (#25)**: `ScriptCompilationService.ValidateTrustModel` delegates the forbidden-API verdict to `ScriptTrustValidator.FindViolations`. The Site Runtime retains its own `CSharpScript.Compile` against the real `ScriptGlobals` for execution.
|
||||
- **Data Connection Layer**: Provides tag value updates to Instance Actors. Receives write requests from Instance Actors. Also feeds Native Alarm Actors: connections implementing `IAlarmSubscribableConnection` (OPC UA A&C servers, MxAccess Gateway) deliver `NativeAlarmTransitionUpdate` events in response to a `SubscribeAlarmsRequest`, and signal `NativeAlarmSourceUnavailable` on connection loss.
|
||||
- **Store-and-Forward Engine**: Handles reliable delivery for external system calls, cached database writes, and notifications submitted by scripts. For the notification category specifically, it forwards to the central cluster for delivery (not directly to SMTP). Owns the site-local operation tracking table that backs `Tracking.Status(id)`.
|
||||
- **External System Gateway**: Provides external system method invocations for scripts.
|
||||
|
||||
@@ -153,7 +153,7 @@ Before a deployment is sent to a site, the Template Engine performs comprehensiv
|
||||
|
||||
- **Flattening**: The full template hierarchy resolves and flattens without errors.
|
||||
- **Naming collision detection**: No duplicate attribute, alarm, or script names in the flattened configuration.
|
||||
- **Script compilation**: All instance scripts and alarm on-trigger scripts are test-compiled and must compile without errors.
|
||||
- **Script compilation and trust check**: All instance scripts and alarm on-trigger scripts are compiled via `ScriptCompiler.TryCompile`, which performs a real Roslyn type-checking compile (using `ScriptCompileSurface` from the Script Analysis component as the globals type) and an authoritative forbidden-API check (via `ScriptTrustValidator.FindViolations`). Scripts with compilation errors, type errors, or forbidden-API violations are rejected. This gate is authoritative — not advisory — meaning alias, `using static`, and `global::` bypasses are caught by semantic symbol resolution.
|
||||
- **Alarm trigger references**: Alarm trigger definitions reference attributes that exist in the flattened configuration.
|
||||
- **Script trigger references**: Script triggers (value change, conditional) reference attributes that exist in the flattened configuration.
|
||||
- **Data connection binding completeness**: Every attribute with a data source reference has a data connection binding assigned on the instance, and the bound data connection name exists as a defined connection at the instance's site.
|
||||
@@ -192,13 +192,14 @@ The same validation logic is available to Design users in the Central UI without
|
||||
|
||||
### Shared Script Validation
|
||||
|
||||
For shared scripts, pre-compilation validation is performed before deployment. Since shared scripts have no instance context, validation is limited to C# syntax and structural correctness.
|
||||
For shared scripts, pre-compilation validation is performed before deployment. Since shared scripts have no instance context, validation uses `RoslynScriptCompiler.ParseDiagnostics` for syntax errors and `ScriptTrustValidator.FindViolations` for the forbidden-API check. Full type-checking compilation is not performed (no globals type is available), but syntax and trust violations are caught and reported.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Configuration Database (MS SQL)**: Stores all templates, instances, areas, and their relationships.
|
||||
- **Security & Auth**: Enforces Design role for template authoring, Deployment role for instance management.
|
||||
- **Configuration Database (via IAuditService)**: All template and instance changes are audit logged.
|
||||
- **Script Analysis (#25)**: `ScriptCompiler.TryCompile` uses `RoslynScriptCompiler` and `ScriptTrustValidator.FindViolations` from this component for the deploy-gate script compilation and forbidden-API check. `ValidationService.CheckExpressionSyntax` uses `ScriptTrustValidator` and `TriggerCompileSurface` for expression trigger validation.
|
||||
|
||||
## Interactions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user