# Phase 2: Core Modeling, Validation & Deployment Contract

**Date**: 2026-03-16
**Status**: Draft

---

## 1. Scope

**Goal**: Template authoring data model, validation pipeline, and the compiled deployment artifact contract are functional. The output of this phase defines exactly what gets deployed to a site.

**Components**:
- Template Engine (full)
- Configuration Database (ITemplateEngineRepository, IDeploymentManagerRepository stubs)

**Testable Outcome**: Complex template trees can be authored, flattened, diffed, and validated programmatically. Revision hashes generated. The flattened configuration output format (the "deployment package") is stable and versioned. All validation rules enforced including semantic checks.

**HighLevelReqs Coverage**: 3.1–3.11, 4.1, 4.5 (Phase 2 portions of split sections as noted)

---

## 2. Prerequisites

- **Phase 0 complete**: Solution skeleton, Commons type system, POCO entity classes, repository interfaces, message contracts, Host skeleton.
- **Phase 1 complete**: Configuration Database (DbContext, EF Core mappings, IAuditService), Security & Auth (role enforcement available for Design/Deployment role gating), Host (startup validation, Akka bootstrap).

Specifically required from earlier phases:
- Commons POCO entities for templates, attributes, alarms, scripts, instances, areas, compositions, connection bindings (REQ-COM-3).
- `ITemplateEngineRepository` interface defined in Commons (REQ-COM-4).
- `IDeploymentManagerRepository` interface defined in Commons (REQ-COM-4).
- `IAuditService` implementation in Configuration Database.
- Shared data types: enums for DataType (Boolean, Integer, Float, String), TriggerType (ValueMatch, RangeViolation, RateOfChange), etc. (REQ-COM-1).
- EF Core DbContext with Fluent API mappings for template domain entities.

---

## 3. Requirements Checklist

Each bullet extracted from docs/requirements/HighLevelReqs.md sections covered by this phase. IDs follow the pattern `[section-N]`.

### 3.1 Template Structure
- `[3.1-1]` Machines are modeled as instances of templates.
- `[3.1-2]` Templates define a set of attributes.
- `[3.1-3]` Each attribute has a lock flag that controls whether it can be overridden downstream.

### 3.2 Attribute Definition
- `[3.2-1]` Attribute has Name (identifier).
- `[3.2-2]` Attribute has Value (default or configured; may be empty if intended for instance-level or data connection binding).
- `[3.2-3]` Attribute has Data Type: fixed set Boolean, Integer, Float, String.
- `[3.2-4]` Attribute has Lock Flag controlling downstream override.
- `[3.2-5]` Attribute has Description (human-readable).
- `[3.2-6]` Attribute has optional Data Source Reference — a relative path within a data connection.
- `[3.2-7]` Template defines what to read (relative path); template does NOT specify which data connection to use.
- `[3.2-8]` Attributes without a data source reference are static configuration values.

### 3.3 Data Connections (Phase 2 portion — model/binding only)
- `[3.3-1]` Data connections are reusable, named resources defined centrally and assigned to specific sites.
- `[3.3-2]` A data connection encapsulates protocol, address, credentials, etc.
- `[3.3-3]` Attributes with a data source reference must be bound to a data connection at instance creation.
- `[3.3-4]` Binding is per-attribute: each attribute with a data source reference individually selects its data connection.
- `[3.3-5]` Different attributes on the same instance may use different data connections.
- `[3.3-6]` Bulk assignment supported (selecting multiple attributes and assigning a connection at once).
- `[3.3-7]` Templates do NOT specify a default connection — binding is an instance-level concern.
- `[3.3-8]` Flattened configuration resolves connection references into concrete connection details paired with attribute relative paths.
- `[3.3-9]` Data connection names are NOT standardized across sites — different sites may have different names for equivalent devices.

**Phase 2 does NOT cover** (owned by Phase 3B): Runtime data connection protocol adapters, subscription management, auto-reconnect, write-back, tag path resolution. Phase 2 covers the data model and binding model only.

### 3.4 Alarm Definitions
- `[3.4-1]` Alarms are first-class template members alongside attributes and scripts.
- `[3.4-2]` Alarms follow the same inheritance, override, and lock rules as attributes.
- `[3.4-3]` Alarm has Name (identifier).
- `[3.4-4]` Alarm has Description (human-readable).
- `[3.4-5]` Alarm has Priority Level (numeric 0–1000).
- `[3.4-6]` Alarm has Lock Flag controlling downstream override.
- `[3.4-7]` Alarm has Trigger Definition: one of Value Match, Range Violation, or Rate of Change.
- `[3.4-8]` Value Match: triggers when monitored attribute equals a predefined value.
- `[3.4-9]` Range Violation: triggers when monitored attribute falls outside an allowed range.
- `[3.4-10]` Rate of Change: triggers when monitored attribute changes faster than a defined threshold.
- `[3.4-11]` Alarm has optional On-Trigger Script reference.
- `[3.4-12]` On-trigger script executes in instance context and can call instance scripts.
- `[3.4-13]` Instance scripts CANNOT call alarm on-trigger scripts — call direction is one-way.

**Note**: `[3.4-12]` and `[3.4-13]` are modeled in Phase 2 (reference validation) and enforced at runtime in Phase 3B.

### 3.5 Template Relationships
- `[3.5-1]` Inheritance (is-a): child template extends parent. Child inherits all attributes, alarms, scripts, and composed feature modules.
- `[3.5-2]` Inheritance: child can override values of non-locked inherited members.
- `[3.5-3]` Inheritance: child can add new attributes, alarms, or scripts not in parent.
- `[3.5-4]` Inheritance: child CANNOT remove attributes, alarms, or scripts defined by parent.
- `[3.5-5]` Composition (has-a): template can nest an instance of another template as a feature module.
- `[3.5-6]` Composition: feature modules can themselves compose other feature modules recursively.
- `[3.5-7]` Naming collisions: if two composed modules define same name for attribute/alarm/script, it is a design-time error.
- `[3.5-8]` Naming collisions: system must detect and report the collision.
- `[3.5-9]` Naming collisions: template cannot be saved until conflict is resolved.

### 3.6 Locking
- `[3.6-1]` Locking applies to attributes, alarms, and scripts uniformly.
- `[3.6-2]` Any member can be locked at the level where it is defined or overridden.
- `[3.6-3]` A locked member CANNOT be overridden by any downstream level (child, composing, or instance).
- `[3.6-4]` An unlocked member CAN be overridden by any downstream level.
- `[3.6-5]` Intermediate locking: any level can lock a member that was unlocked upstream.
- `[3.6-6]` Once locked, it remains locked for all levels below — downstream CANNOT unlock it.

### 3.6 Attribute Resolution Order
- `[3.6R-1]` Resolution from most-specific to least-specific; first value encountered wins.
- `[3.6R-2]` Order: Instance → Child Template (most derived first) → Composing Template → Composed Module (recursively resolved).
- `[3.6R-3]` Override only permitted if the member has NOT been locked at a higher-priority level.

### 3.7 Override Scope
- `[3.7-1]` Inheritance: child templates can override non-locked members from parent, including members originating from composed feature modules.
- `[3.7-2]` Composition: a template that composes a feature module can override non-locked members within that module.
- `[3.7-3]` Overrides can "pierce" into composed modules — a child template can override members inside a feature module it inherited from its parent.

### 3.8 Instance Rules
- `[3.8-1]` An instance is a deployed occurrence of a template at a site.
- `[3.8-2]` Instances CAN override values of non-locked attributes.
- `[3.8-3]` Instances CANNOT add new attributes.
- `[3.8-4]` Instances CANNOT remove attributes.
- `[3.8-5]` Instance structure (attributes, composed modules) is strictly defined by its template.
- `[3.8-6]` Each instance is assigned to an area within its site.

### 3.9 Template Deployment & Change Propagation (Phase 2 portion)
- `[3.9-1]` Template changes are NOT automatically propagated to deployed instances.
- `[3.9-2]` System maintains two views: Deployed Configuration and Template-Derived Configuration.
- `[3.9-3]` System must show differences between deployed and template-derived configuration.
- `[3.9-4]` No rollback support required. System tracks current deployed state. (Note: deployment history records exist for audit purposes per Configuration Database schema, but no rollback mechanism is provided.)
- `[3.9-6]` Deployment is performed at individual instance level — engineer explicitly commands update. *(Phase 2 models the data; Phase 3C implements the deployment pipeline execution.)*
- `[3.9-5]` Concurrent editing uses last-write-wins — no pessimistic locking or optimistic concurrency conflict detection on templates.

**Phase 2 does NOT cover** (owned by Phase 3C/6): Deployment pipeline execution (the act of sending to site and tracking status). Phase 2 covers the diff calculation, template-derived configuration computation, and the data model for per-instance deployment. `[3.9-6]` is extracted here for traceability but the pipeline execution is Phase 3C.

### 3.10 Areas (Phase 2 portion — model)
- `[3.10-1]` Areas are predefined hierarchical groupings associated with a site.
- `[3.10-2]` Areas stored in the configuration database.
- `[3.10-3]` Areas support parent-child relationships (e.g., Plant → Building → Production Line → Cell).
- `[3.10-4]` Each instance is assigned to an area within its site.

- `[3.10-5]` Areas are used for filtering and finding instances in the central UI. *(Phase 4 — UI concern.)*
- `[3.10-6]` Area definitions are managed by users with the Admin role. *(Phase 4 — role enforcement in UI. Phase 2 provides the CRUD operations; role gating is applied at the service/controller layer using Phase 1 authorization infrastructure.)*

**Phase 2 does NOT cover** (owned by Phase 4): `[3.10-5]` area filtering in UI, `[3.10-6]` Admin role enforcement in UI. Phase 2 covers the data model and CRUD operations.

### 3.11 Pre-Deployment Validation
- `[3.11-1]` Flattening: full template hierarchy resolves and flattens successfully.
- `[3.11-2]` Naming collision detection: no duplicate attribute, alarm, or script names in flattened configuration.
- `[3.11-3]` Script compilation: all instance scripts and alarm on-trigger scripts test-compile without errors.
- `[3.11-4]` Alarm trigger references: alarm trigger definitions reference attributes that exist in flattened configuration.
- `[3.11-5]` Script trigger references: script triggers (value change, conditional) reference attributes that exist in flattened configuration.
- `[3.11-6]` Data connection binding completeness: every attribute with a data source reference has a connection binding assigned, and the bound connection name exists at the instance's site.
- `[3.11-7]` Exception: validation does NOT verify that data source relative paths resolve to real tags on physical devices — that is a runtime concern.
- `[3.11-8]` Validation available on demand in Central UI for Design users during template authoring.
- `[3.11-9]` For shared scripts, pre-compilation validation is performed — limited to C# syntax and structural correctness (no instance context).

### 4.1 Script Definitions (Phase 2 portion — model)
- `[4.1-1]` Scripts are C# and defined at template level as first-class template members.
- `[4.1-2]` Scripts follow same inheritance, override, and lock rules as attributes.
- `[4.1-3]` Scripts are deployed to sites as part of flattened instance configuration.
- `[4.1-4]` Scripts are compiled at the site; pre-compilation validation occurs at central before deployment.
- `[4.1-5]` Scripts can optionally define input parameters (name and data type per parameter). Scripts without parameters accept no arguments.
- `[4.1-6]` Scripts can optionally define return value definition (field names and data types). Supports single objects and lists of objects. Scripts without return definition return void.
- `[4.1-7]` Return values used when called by other scripts or Inbound API; when invoked by trigger, return value is discarded.

**Phase 2 does NOT cover** (owned by Phase 3B): Script triggers (interval, value change, conditional), minimum time between runs, runtime compilation, Script Actors, Script Execution Actors. Phase 2 covers the script data model, inheritance/override/lock, parameter/return definitions, and pre-compilation validation.

### 4.5 Shared Scripts (Phase 2 portion — model)
- `[4.5-1]` Shared scripts are NOT associated with any template — system-wide library.
- `[4.5-2]` Shared scripts can optionally define input parameters and return value definitions, same rules as template-level scripts.
- `[4.5-3]` Managed by users with the Design role.

**Phase 2 does NOT cover** (owned by Phase 3B): Runtime deployment to sites, inline execution, shared scripts not available on central. Phase 2 covers the data model, CRUD, and syntax/structural validation.

---

## 4. Design Constraints Checklist

Constraints from CLAUDE.md Key Design Decisions and docs/requirements/Component-TemplateEngine.md / docs/requirements/Component-ConfigurationDatabase.md.

### From CLAUDE.md Key Design Decisions

- `[KDD-deploy-1]` Pre-deployment validation includes semantic checks (call targets, argument types, trigger operand types).
- `[KDD-deploy-2]` Composed member addressing: `[ModuleInstanceName].[MemberName]`. Nested: `[Outer].[Inner].[Member]`.
- `[KDD-deploy-3]` Override granularity defined per entity type and per field.
- `[KDD-deploy-4]` Template graph acyclicity enforced on save.
- `[KDD-deploy-5]` Flattened configs include revision hash for staleness detection.
- `[KDD-deploy-10]` Last-write-wins for concurrent template editing (no optimistic concurrency on templates).
- `[KDD-deploy-12]` Naming collisions in composed feature modules are design-time errors.

### From docs/requirements/Component-TemplateEngine.md

- `[CD-TE-1]` Template has unique name/ID.
- `[CD-TE-2]` Template cannot be deleted if referenced by instances or child templates.
- `[CD-TE-3]` Override granularity — Attributes: Value and Description overridable; Data Type and Data Source Reference fixed. Lock applies to entire attribute.
- `[CD-TE-4]` Override granularity — Alarms: Priority, Trigger Definition (thresholds/ranges/rates), Description, On-Trigger Script reference overridable; Name and Trigger Type fixed. Lock applies to entire alarm.
- `[CD-TE-5]` Override granularity — Scripts: C# source code, Trigger configuration, minimum time between runs, parameter/return definitions overridable; Name fixed. Lock applies to entire script.
- `[CD-TE-6]` Composed module members: composing template or child template can override non-locked members using canonical path-qualified name.
- `[CD-TE-7]` Collision detection on canonical names — two modules can define same member name if module instance names differ.
- `[CD-TE-8]` Collision detection is performed recursively for nested module compositions.
- `[CD-TE-9]` All internal references use canonical names (triggers, scripts, diffs, stream topics, UI display).
- `[CD-TE-10]` Composing template's own members (not from a module) have no prefix — top-level names.
- `[CD-TE-11]` Flattening: resolve data connection bindings — replace connection name references with concrete connection details.
- `[CD-TE-12]` Diff output identifies added, removed, and changed attributes/alarms/scripts.
- `[CD-TE-13]` Semantic validation: script call targets (CallScript, CallShared) must reference existing scripts.
- `[CD-TE-14]` Semantic validation: parameter count and data types at call sites must match target script definitions.
- `[CD-TE-15]` Semantic validation: return type compatibility — return type definition must match caller expectations.
- `[CD-TE-16]` Semantic validation: trigger operand types — alarm triggers and script conditional triggers must reference attributes with compatible data types (e.g., Range Violation requires numeric).
- `[CD-TE-17]` Graph acyclicity: template cannot inherit from itself or any descendant.
- `[CD-TE-18]` Graph acyclicity: template cannot compose itself or any ancestor/descendant creating circular composition.
- `[CD-TE-19]` Acyclicity checks performed on save.
- `[CD-TE-20]` Revision hash computed from resolved content. Used for staleness detection and diff correlation.
- `[CD-TE-21]` On-demand validation: same logic as pre-deployment, without triggering deployment.
- `[CD-TE-22]` Shared script validation limited to C# syntax and structural correctness (no instance context).
- `[CD-TE-23]` Instance can be in enabled or disabled state.
- `[CD-TE-24]` Instance deletion blocked if site is unreachable.
- `[CD-TE-25]` Script has trigger configuration: Interval, Value Change, Conditional, or invoked by alarm/other script.
- `[CD-TE-26]` Script has optional minimum time between runs.

### From docs/requirements/Component-ConfigurationDatabase.md

- `[CD-CDB-1]` ITemplateEngineRepository covers: templates, attributes, alarms, scripts, compositions, instances, overrides, connection bindings, areas.
- `[CD-CDB-2]` IDeploymentManagerRepository covers: current deployment status per instance, deployed configuration snapshots, system-wide artifact deployment status per site.
- `[CD-CDB-3]` Template editing uses last-write-wins; optimistic concurrency intentionally not applied to template content.
- `[CD-CDB-4]` Optimistic concurrency on deployment status records and instance lifecycle state via EF Core rowversion/concurrency tokens.
- `[CD-CDB-5]` Repository implementations use DbContext internally with POCO entities from Commons.
- `[CD-CDB-6]` Consuming components depend only on Commons — never reference Configuration Database or EF Core directly.
- `[CD-CDB-7]` Shared Scripts table: name, C# source code, parameter definitions, return value definitions.
- `[CD-CDB-8]` Sites table: name, identifier, description.
- `[CD-CDB-9]` Data Connections table: name, protocol type, connection details, with site assignments.

---

## 5. Work Packages

### WP-1: Template CRUD with Inheritance

**Description**: Implement create, read, update, delete operations for templates, including inheritance (parent-child) relationships. Templates have unique names, optional parent reference. Enforce deletion constraints.

**Acceptance Criteria**:
- Template can be created with a unique name/ID. (`[3.1-1]`, `[CD-TE-1]`)
- Template can optionally extend a parent template. (`[3.5-1]`)
- Template CRUD operations persist to configuration database via ITemplateEngineRepository. (`[CD-CDB-1]`)
- Template cannot be deleted if any instances reference it. (`[CD-TE-2]`)
- Template cannot be deleted if any child templates reference it. (`[CD-TE-2]`)
- Attempting to delete a referenced template returns a clear error identifying the referencing entities.
- Template updates use last-write-wins — no optimistic concurrency tokens on template content. (`[3.9-5]`, `[KDD-deploy-10]`, `[CD-CDB-3]`)
- All template changes are audit logged via IAuditService.

**Estimated Complexity**: M

**Requirements Traced**: `[3.1-1]`, `[3.5-1]`, `[3.9-5]`, `[CD-TE-1]`, `[CD-TE-2]`, `[KDD-deploy-10]`, `[CD-CDB-1]`, `[CD-CDB-3]`

---

### WP-2: Attribute Definitions with Lock Flags

**Description**: Implement attribute definitions on templates with all metadata fields and lock flag behavior.

**Acceptance Criteria**:
- Attributes define: Name, Value, Data Type (Boolean/Integer/Float/String), Lock Flag, Description. (`[3.2-1]`–`[3.2-5]`, `[3.1-2]`, `[3.1-3]`)
- Attributes optionally define Data Source Reference (relative path). (`[3.2-6]`)
- Template defines what to read; does NOT specify which data connection. (`[3.2-7]`, `[3.3-7]`)
- Attributes without a data source reference are treated as static configuration values. (`[3.2-8]`)
- Value may be empty (null/default) for instance-level or connection-bound attributes. (`[3.2-2]`)
- Lock flag stored per attribute. (`[3.6-1]`, `[3.6-2]`)

**Estimated Complexity**: S

**Requirements Traced**: `[3.1-2]`, `[3.1-3]`, `[3.2-1]`–`[3.2-8]`, `[3.3-7]`, `[3.6-1]`, `[3.6-2]`

---

### WP-3: Alarm Definitions

**Description**: Implement alarm definitions on templates as first-class members with trigger configurations.

**Acceptance Criteria**:
- Alarm defines: Name, Description, Priority Level (0–1000), Lock Flag. (`[3.4-3]`–`[3.4-6]`)
- Alarm has trigger definition — one of: Value Match, Range Violation, Rate of Change. (`[3.4-7]`)
- Value Match: stores monitored attribute reference and predefined match value. (`[3.4-8]`)
- Range Violation: stores monitored attribute reference and allowed range (min/max). (`[3.4-9]`)
- Rate of Change: stores monitored attribute reference and rate threshold. (`[3.4-10]`)
- Alarm optionally references an on-trigger script. (`[3.4-11]`)
- Alarms are first-class template members alongside attributes and scripts. (`[3.4-1]`)
- Alarms follow inheritance, override, and lock rules. (`[3.4-2]`)

**Estimated Complexity**: M

**Requirements Traced**: `[3.4-1]`–`[3.4-11]`

---

### WP-4: Script Definitions (Model)

**Description**: Implement script definitions on templates as first-class members with parameter and return value definitions. Model only — runtime compilation/execution is Phase 3B.

**Acceptance Criteria**:
- Script defines: Name, Lock Flag, C# source code. (`[4.1-1]`)
- Script has trigger configuration field: Interval, Value Change, Conditional, or invoked by alarm/other script. (`[CD-TE-25]`)
- Script has optional minimum time between runs. (`[CD-TE-26]`)
- Script optionally defines input parameters (name + data type per parameter). (`[4.1-5]`)
- Scripts without parameter definitions accept no arguments. (`[4.1-5]`)
- Script optionally defines return value definition (field names + data types). (`[4.1-6]`)
- Return values support single objects and lists of objects. (`[4.1-6]`)
- Scripts without return definition return void. (`[4.1-6]`)
- Scripts follow same inheritance, override, and lock rules as attributes. (`[4.1-2]`)
- Scripts are included in flattened instance configuration. (`[4.1-3]`)

**Estimated Complexity**: M

**Requirements Traced**: `[4.1-1]`–`[4.1-6]`, `[CD-TE-25]`, `[CD-TE-26]`

---

### WP-5: Shared Script CRUD and Validation

**Description**: Implement shared script definitions (system-wide library) with CRUD operations and syntax/structural validation.

**Acceptance Criteria**:
- Shared scripts are not associated with any template — system-wide. (`[4.5-1]`)
- Shared script defines: name, C# source code, optional parameter definitions, optional return value definitions. (`[4.5-2]`, `[CD-CDB-7]`)
- Parameter and return value definitions follow same rules as template scripts. (`[4.5-2]`)
- CRUD operations persist via repository (shared scripts are stored in the Shared Scripts table per `[CD-CDB-7]`; the repository interface assignment is an implementation detail — either ITemplateEngineRepository is extended or a dedicated interface is created).
- Pre-compilation validation for shared scripts is limited to C# syntax and structural correctness (no instance context). (`[3.11-9]`, `[CD-TE-22]`)
- Validation returns actionable error messages (line numbers, error descriptions).
- Service layer enforces Design role for shared script management. (`[4.5-3]`)
- All shared script changes are audit logged.

**Estimated Complexity**: M

**Requirements Traced**: `[4.5-1]`–`[4.5-3]`, `[3.11-9]`, `[CD-TE-22]`, `[CD-CDB-7]`

---

### WP-6: Composition with Recursive Nesting

**Description**: Implement composition (has-a) relationships: a template nests instances of other templates as feature modules, with recursive nesting support.

**Acceptance Criteria**:
- Template can compose zero or more feature modules (instances of other templates). (`[3.5-5]`)
- Each composition relationship has a module instance name. (`[KDD-deploy-2]`)
- Feature modules can themselves compose other feature modules recursively. (`[3.5-6]`)
- Composition relationships stored in Template Compositions table. (`[CD-CDB-1]`)
- Child template inherits all composed feature modules from parent. (`[3.5-1]`)

**Estimated Complexity**: M

**Requirements Traced**: `[3.5-1]`, `[3.5-5]`, `[3.5-6]`, `[KDD-deploy-2]`, `[CD-CDB-1]`

---

### WP-7: Path-Qualified Canonical Naming

**Description**: Implement path-qualified canonical naming for composed members: `[ModuleInstanceName].[MemberName]`, with nested path extension.

**Acceptance Criteria**:
- Composed module members are addressed as `[ModuleInstanceName].[MemberName]`. (`[KDD-deploy-2]`)
- For nested compositions, path extends: `[OuterModule].[InnerModule].[MemberName]`. (`[KDD-deploy-2]`)
- Composing template's own (non-module) members have no prefix — top-level names. (`[CD-TE-10]`)
- All internal references (triggers, scripts, diffs) use canonical names. (`[CD-TE-9]`)

**Estimated Complexity**: M

**Requirements Traced**: `[KDD-deploy-2]`, `[CD-TE-9]`, `[CD-TE-10]`

---

### WP-8: Override Granularity Enforcement

**Description**: Implement per-entity-type, per-field override granularity rules.

**Acceptance Criteria**:
- **Attributes**: Value and Description are overridable; Data Type and Data Source Reference are fixed by defining level. Lock applies to entire attribute. (`[CD-TE-3]`, `[KDD-deploy-3]`)
- **Alarms**: Priority Level, Trigger Definition (thresholds/ranges/rates), Description, On-Trigger Script reference are overridable; Name and Trigger Type are fixed. Lock applies to entire alarm. (`[CD-TE-4]`, `[KDD-deploy-3]`)
- **Scripts**: C# source code, Trigger configuration, minimum time between runs, parameter/return definitions are overridable; Name is fixed. Lock applies to entire script. (`[CD-TE-5]`, `[KDD-deploy-3]`)
- Composed module members: composing template or child template can override non-locked members using canonical path-qualified name. (`[CD-TE-6]`)
- Attempting to override a fixed field (e.g., attribute Data Type) returns an error.
- Attempting to override a locked member returns an error. (`[3.6-3]`)

**Estimated Complexity**: M

**Requirements Traced**: `[KDD-deploy-3]`, `[CD-TE-3]`–`[CD-TE-6]`, `[3.6-3]`

---

### WP-9: Locking Rules

**Description**: Implement the full locking semantics across inheritance, composition, and instance levels.

**Acceptance Criteria**:
- Locking applies uniformly to attributes, alarms, and scripts. (`[3.6-1]`)
- Any level can lock a member at the level where it is defined or overridden. (`[3.6-2]`)
- A locked member CANNOT be overridden by any downstream level. (`[3.6-3]`)
- An unlocked member CAN be overridden by any downstream level. (`[3.6-4]`)
- Intermediate locking: any level can lock a previously unlocked member. (`[3.6-5]`)
- Once locked, it stays locked — downstream CANNOT unlock it. (`[3.6-6]`)
- Override only permitted if member is NOT locked at a higher-priority level. (`[3.6R-3]`)
- Test: parent locks an attribute → child attempt to override → rejected.
- Test: parent unlocked → child locks → grandchild attempt to override → rejected.
- Test: parent unlocked → child unlocked → grandchild overrides → succeeds.

**Estimated Complexity**: M

**Requirements Traced**: `[3.6-1]`–`[3.6-6]`, `[3.6R-3]`

---

### WP-10: Inheritance Override Scope

**Description**: Implement override scope rules for inheritance relationships.

**Acceptance Criteria**:
- Child templates can override non-locked members from parent. (`[3.5-2]`, `[3.7-1]`)
- Child can add new attributes, alarms, or scripts not in parent. (`[3.5-3]`)
- Child CANNOT remove attributes, alarms, or scripts defined by parent. (`[3.5-4]`)
- Child can override members originating from composed feature modules inherited from parent. (`[3.7-1]`)
- Overrides can pierce into composed modules — child can override members inside inherited feature module. (`[3.7-3]`)
- Test: child adds attribute not in parent → succeeds.
- Test: child attempts to remove parent attribute → rejected.
- Test: child overrides non-locked attribute in inherited composed module → succeeds.

**Estimated Complexity**: M

**Requirements Traced**: `[3.5-2]`–`[3.5-4]`, `[3.7-1]`, `[3.7-3]`

---

### WP-11: Composition Override Scope

**Description**: Implement override scope rules for composition relationships.

**Acceptance Criteria**:
- Composing template can override non-locked members within composed module. (`[3.7-2]`)
- Overrides use canonical path-qualified names. (`[CD-TE-6]`)
- Test: composing template overrides non-locked member in module → succeeds.
- Test: composing template overrides locked member in module → rejected.

**Estimated Complexity**: S

**Requirements Traced**: `[3.7-2]`, `[CD-TE-6]`

---

### WP-12: Naming Collision Detection

**Description**: Implement naming collision detection for composed feature modules, operating on canonical names.

**Acceptance Criteria**:
- When composing two or more modules, detect collisions across attribute, alarm, and script names. (`[3.5-7]`, `[3.5-8]`)
- Collision detection operates on canonical names — two modules CAN define same member name if module instance names differ. (`[CD-TE-7]`)
- Collision detection is performed recursively for nested module compositions. (`[CD-TE-8]`)
- Collision between module member and composing template's own top-level member is detected.
- Template CANNOT be saved if collision exists. (`[3.5-9]`, `[KDD-deploy-12]`)
- Error message identifies the conflicting names and their sources.
- Test: two modules with same attribute name → collision detected.
- Test: two modules with same name but different module instance names → no collision (canonical names differ).
- Test: nested module introduces collision → detected recursively.

**Estimated Complexity**: M

**Requirements Traced**: `[3.5-7]`–`[3.5-9]`, `[KDD-deploy-12]`, `[CD-TE-7]`, `[CD-TE-8]`

---

### WP-13: Graph Acyclicity Enforcement

**Description**: Enforce that inheritance and composition graphs are acyclic, checked on save.

**Acceptance Criteria**:
- A template cannot inherit from itself. (`[CD-TE-17]`)
- A template cannot inherit from any descendant in its inheritance chain. (`[CD-TE-17]`)
- A template cannot compose itself. (`[CD-TE-18]`)
- A template cannot compose any ancestor/descendant that would create circular composition. (`[CD-TE-18]`)
- Acyclicity checks are performed on save (not deferred). (`[CD-TE-19]`, `[KDD-deploy-4]`)
- Error message identifies the cycle.
- Test: A inherits B inherits A → rejected on save.
- Test: A composes B composes A → rejected on save.
- Test: A inherits B, B composes C, C composes A → rejected on save.

**Estimated Complexity**: M

**Requirements Traced**: `[KDD-deploy-4]`, `[CD-TE-17]`–`[CD-TE-19]`

---

### WP-14: Flattening Algorithm

**Description**: Implement the full resolution chain that produces a flat, deployable configuration from a template + instance overrides.

**Acceptance Criteria**:
- Resolution order: Instance → Child Template (most derived first) → Composing Template → Composed Module (recursively). (`[3.6R-1]`, `[3.6R-2]`)
- Walk inheritance chain applying overrides at each level, respecting locks. (docs/requirements/Component-TE flattening step 2)
- Resolve composed feature modules, applying overrides from composing templates, respecting locks. (docs/requirements/Component-TE flattening step 3)
- Apply instance-level overrides, respecting locks. (docs/requirements/Component-TE flattening step 4)
- Resolve data connection bindings — replace connection name references with concrete connection details from site. (`[3.3-8]`, `[CD-TE-11]`)
- Output a flat structure: list of attributes with resolved values and data source addresses, list of alarms with resolved trigger definitions, list of scripts with resolved code and triggers. (docs/requirements/Component-TE flattening step 6)
- Flattening success is a pre-deployment validation check. (`[3.11-1]`)
- Test: multi-level inheritance with overrides and locks → correct resolution.
- Test: nested composition with overrides → correct canonical names.
- Test: connection binding resolution → concrete details in output.

**Estimated Complexity**: L

**Requirements Traced**: `[3.6R-1]`, `[3.6R-2]`, `[3.3-8]`, `[3.11-1]`, `[CD-TE-11]`

---

### WP-15: Diff Calculation

**Description**: Implement diff between deployed configuration and current template-derived configuration.

**Acceptance Criteria**:
- Can compare currently deployed flat config against current template-derived flat config. (`[3.9-2]`, `[3.9-3]`)
- Diff output identifies added, removed, and changed attributes/alarms/scripts. (`[CD-TE-12]`)
- Changes are NOT auto-propagated — diff is informational. (`[3.9-1]`)
- No rollback mechanism; the system does not provide a way to revert to a previous deployment. Deployment history records exist in the database for audit purposes (per Configuration Database schema), but no rollback operation is exposed. (`[3.9-4]`)
- Test: add attribute to template → diff shows added.
- Test: change attribute value → diff shows changed with old/new.
- Test: remove attribute from derived config (via composition change) → diff shows removed.

**Estimated Complexity**: M

**Requirements Traced**: `[3.9-1]`–`[3.9-4]`, `[CD-TE-12]`

---

### WP-16: Revision Hash Generation

**Description**: Compute a revision hash from the resolved flattened content for staleness detection.

**Acceptance Criteria**:
- Each flattened configuration output includes a revision hash. (`[KDD-deploy-5]`, `[CD-TE-20]`)
- Hash is computed deterministically from resolved content (same content → same hash).
- Hash is used for staleness detection: comparing deployed revision to current template-derived revision without full diff. (`[CD-TE-20]`)
- Hash is used for diff correlation: ensuring diffs are computed against a consistent baseline. (`[CD-TE-20]`)
- Test: identical content → identical hash.
- Test: changed content → different hash.

**Estimated Complexity**: S

**Requirements Traced**: `[KDD-deploy-5]`, `[CD-TE-20]`

---

### WP-17: Deployment Package Contract

**Description**: Define the exact serialization format of a flattened configuration — the stable boundary between Template Engine, Deployment Manager, and Site Runtime.

**Acceptance Criteria**:
- Deployment package format is explicitly defined and versioned.
- Package contains: all resolved attributes (values, data types, data source addresses with connection details), all resolved alarms (trigger definitions with resolved attribute references), all resolved scripts (source code, trigger configuration, parameter/return definitions). (docs/requirements/Component-TE flattening step 6)
- Package includes the revision hash. (`[KDD-deploy-5]`)
- Scripts are included for deployment to sites as part of flattened config. (`[4.1-3]`)
- Pre-compilation validation occurs at central; actual compilation at site. (`[4.1-4]`)
- Return values noted in script definitions for caller compatibility. When invoked by trigger (interval, value change, conditional, alarm), return value is discarded — the contract documents this behavior. (`[4.1-7]`)
- Format is serializable/deserializable for transmission and SQLite persistence.
- Format supports versioning for forward compatibility.

**Estimated Complexity**: M

**Requirements Traced**: `[4.1-3]`, `[4.1-4]`, `[4.1-7]`, `[KDD-deploy-5]`

---

### WP-18: Pre-Deployment Validation Pipeline

**Description**: Implement the comprehensive validation pipeline that runs before deployment and on demand.

**Acceptance Criteria**:
- Validates flattening success. (`[3.11-1]`)
- Validates no naming collisions in flattened configuration. (`[3.11-2]`)
- Validates all scripts test-compile (instance scripts + alarm on-trigger scripts). (`[3.11-3]`)
- Validates alarm trigger references exist in flattened configuration. (`[3.11-4]`)
- Validates script trigger references (value change, conditional) exist in flattened configuration. (`[3.11-5]`)
- Validates data connection binding completeness: every attribute with data source reference has a binding, and bound connection name exists at site. (`[3.11-6]`)
- Does NOT verify data source relative paths resolve to real tags on devices. (`[3.11-7]`)
- Returns structured validation results: list of errors with categories, entity references, and descriptions.
- Pipeline can be invoked without triggering deployment (on-demand). (`[3.11-8]`, `[CD-TE-21]`)

**Estimated Complexity**: L

**Requirements Traced**: `[3.11-1]`–`[3.11-8]`, `[CD-TE-21]`

---

### WP-19: Semantic Validation

**Description**: Implement static semantic checks beyond compilation, as part of the pre-deployment validation pipeline.

**Acceptance Criteria**:
- Script call targets: `Instance.CallScript()` and `Scripts.CallShared()` targets must reference scripts that exist in flattened configuration or shared script library. (`[CD-TE-13]`, `[KDD-deploy-1]`)
- Argument compatibility: parameter count and data types at call sites must match target script's parameter definitions. (`[CD-TE-14]`, `[KDD-deploy-1]`)
- Return type compatibility: if return value is used, return type definition must match caller expectations. (`[CD-TE-15]`, `[KDD-deploy-1]`)
- Trigger operand types: alarm triggers and script conditional triggers must reference attributes with compatible data types (e.g., Range Violation requires numeric). (`[CD-TE-16]`, `[KDD-deploy-1]`)
- On-trigger script reference validation: referenced script must exist. (`[3.4-11]`, `[3.4-12]`)
- One-way call direction modeled: alarm on-trigger scripts can reference instance scripts, but instance scripts cannot call alarm on-trigger scripts. (`[3.4-13]`)
- Errors are detailed: identify the call site, the expected signature, and the actual signature.

**Estimated Complexity**: L

**Requirements Traced**: `[KDD-deploy-1]`, `[CD-TE-13]`–`[CD-TE-16]`, `[3.4-11]`–`[3.4-13]`

---

### WP-20: Instance CRUD

**Description**: Implement instance creation from template, attribute overrides, area assignment, and data connection binding.

**Acceptance Criteria**:
- Instance is created from a template and associated with a specific site. (`[3.8-1]`)
- Instance assigned to an area within its site. (`[3.8-6]`, `[3.10-4]`)
- Instance CAN override values of non-locked attributes. (`[3.8-2]`)
- Instance CANNOT add new attributes. (`[3.8-3]`)
- Instance CANNOT remove attributes. (`[3.8-4]`)
- Instance structure defined by template. (`[3.8-5]`)
- Instance can be in enabled or disabled state. (`[CD-TE-23]`)
- Instance lifecycle state (enabled/disabled) uses optimistic concurrency via EF Core rowversion/concurrency token. (`[CD-CDB-4]`)
- Per-attribute data connection binding: each attribute with data source reference individually selects its data connection. (`[3.3-3]`, `[3.3-4]`)
- Different attributes on same instance may use different connections. (`[3.3-5]`)
- Bulk assignment: assign a data connection to multiple attributes at once. (`[3.3-6]`)
- Bound data connection must be assigned to the instance's site. (`[3.3-1]`)
- Instance overrides and bindings persisted via ITemplateEngineRepository. (`[CD-CDB-1]`)
- Instance deletion blocked if site is unreachable (modeled — actual enforcement is Phase 3C). (`[CD-TE-24]`)
- All instance changes are audit logged.

**Estimated Complexity**: L

**Requirements Traced**: `[3.8-1]`–`[3.8-6]`, `[3.10-4]`, `[3.3-1]`, `[3.3-3]`–`[3.3-6]`, `[CD-TE-23]`, `[CD-TE-24]`, `[CD-CDB-1]`

---

### WP-21: Site and Data Connection Management

**Description**: Implement CRUD for site definitions and data connections, including site assignment.

**Acceptance Criteria**:
- Site defines: name, identifier, description. (`[CD-CDB-8]`)
- Data connection defines: name, protocol type, connection details. (`[CD-CDB-9]`, `[3.3-2]`)
- Data connections are centrally defined and assigned to specific sites. (`[3.3-1]`)
- Data connection names are NOT standardized across sites — the model allows different sites to have data connections with different names for equivalent devices; no cross-site name validation or normalization is performed. (`[3.3-9]`)
- Test: two sites can have data connections with different names; no constraint enforces name matching. (`[3.3-9]`)
- CRUD operations persist via ITemplateEngineRepository. (`[CD-CDB-1]`)
- All site and data connection changes are audit logged.

**Estimated Complexity**: S

**Requirements Traced**: `[3.3-1]`, `[3.3-2]`, `[3.3-9]`, `[CD-CDB-8]`, `[CD-CDB-9]`, `[CD-CDB-1]`

---

### WP-22: Area Management

**Description**: Implement hierarchical area CRUD per site.

**Acceptance Criteria**:
- Areas are predefined hierarchical groupings associated with a site. (`[3.10-1]`)
- Areas stored in configuration database. (`[3.10-2]`)
- Areas support parent-child relationships. (`[3.10-3]`)
- Each instance is assigned to an area. (`[3.10-4]`)
- CRUD operations for areas. Areas can be created, updated, and deleted.
- Area deletion constrained if instances are assigned to it.
- All area changes are audit logged.

**Estimated Complexity**: S

**Requirements Traced**: `[3.10-1]`–`[3.10-4]`, `[CD-CDB-1]`

---

### WP-23: ITemplateEngineRepository Implementation

**Description**: Implement the EF Core repository for all template domain entities.

**Acceptance Criteria**:
- Repository covers: templates, attributes, alarms, scripts, compositions, instances, overrides, connection bindings, areas. (`[CD-CDB-1]`) Note: shared scripts (`[CD-CDB-7]`) may be added to this repository or served by a separate interface — decide during implementation. The docs/requirements/Component-ConfigurationDatabase.md scope for ITemplateEngineRepository does not explicitly include shared scripts; if a separate interface is warranted, create one.
- Implementation uses DbContext internally with POCO entities from Commons. (`[CD-CDB-5]`)
- Consuming components depend only on Commons interfaces. (`[CD-CDB-6]`)
- Unit-of-work support: multiple operations commit in a single transaction.
- All audit logging integrated via IAuditService within same transaction.

**Estimated Complexity**: L

**Requirements Traced**: `[CD-CDB-1]`, `[CD-CDB-5]`, `[CD-CDB-6]`

---

### WP-24: IDeploymentManagerRepository Stubs

**Description**: Create stub implementation of IDeploymentManagerRepository sufficient for storing deployed configuration snapshots and revision hashes for diff/staleness support.

**Acceptance Criteria**:
- Repository supports storing deployed configuration snapshot per instance. (`[CD-CDB-2]`)
- Repository supports querying current deployment status per instance. (`[CD-CDB-2]`)
- Optimistic concurrency on deployment status records via rowversion. (`[CD-CDB-4]`)
- Stub level: sufficient for Phase 2 diff calculation and revision comparison. Full deployment pipeline operations deferred to Phase 3C.

**Estimated Complexity**: S

**Requirements Traced**: `[CD-CDB-2]`, `[CD-CDB-4]`

---

### WP-25: Template Deletion Constraint Enforcement

**Description**: Enforce that templates cannot be deleted when referenced.

**Acceptance Criteria**:
- Template cannot be deleted if any instances reference it. (`[CD-TE-2]`)
- Template cannot be deleted if any child templates reference it. (`[CD-TE-2]`)
- Template cannot be deleted if any other template composes it as a feature module. (Implied by `[CD-TE-2]` — a composed template is referenced by the composing template's composition relationship. This is a stricter but logically consistent interpretation: if a template is composed, removing it would break the composing template.)
- Error message identifies all referencing entities.
- Test: delete template with instances → rejected.
- Test: delete template with child templates → rejected.
- Test: delete template composed by another → rejected.
- Test: delete unreferenced template → succeeds.

**Estimated Complexity**: S

**Requirements Traced**: `[CD-TE-2]`

---

### WP-26: Unit Tests — Flattening

**Description**: Comprehensive unit tests for the flattening algorithm.

**Acceptance Criteria**:
- Single template (no inheritance, no composition) → flat output matches template.
- Two-level inheritance with overrides → correct resolution.
- Three-level inheritance with intermediate locks → locked values preserved.
- Single composition → module members have canonical names.
- Nested composition (module composes module) → correct nested canonical names.
- Inheritance + composition → child overrides module member → correct.
- Instance overrides → applied over template chain.
- Connection binding resolution → concrete details in output.
- Empty values resolved correctly (instance-level fill-in).
- All alarm and script members included with resolved fields.

**Estimated Complexity**: L

**Requirements Traced**: `[3.6R-1]`, `[3.6R-2]`, `[3.3-8]`, `[3.11-1]`, all WP-14 requirements

---

### WP-27: Unit Tests — Validation

**Description**: Comprehensive unit tests for the pre-deployment validation pipeline including semantic checks.

**Acceptance Criteria**:
- Valid configuration → passes all checks.
- Missing connection binding → binding completeness error. (`[3.11-6]`)
- Non-existent alarm trigger attribute → reference error. (`[3.11-4]`)
- Non-existent script trigger attribute → reference error. (`[3.11-5]`)
- Script compilation error → compilation error reported. (`[3.11-3]`)
- CallScript target does not exist → semantic error. (`[CD-TE-13]`)
- CallScript parameter count mismatch → semantic error. (`[CD-TE-14]`)
- CallScript parameter type mismatch → semantic error. (`[CD-TE-14]`)
- Return type mismatch → semantic error. (`[CD-TE-15]`)
- Range Violation on non-numeric attribute → trigger operand type error. (`[CD-TE-16]`)
- Validation does NOT check device tag path resolution → passes even with arbitrary paths. (`[3.11-7]`)
- On-demand validation returns same results as pre-deployment. (`[3.11-8]`)
- Shared script syntax error → structural validation error. (`[3.11-9]`)

**Estimated Complexity**: L

**Requirements Traced**: `[3.11-1]`–`[3.11-9]`, `[CD-TE-13]`–`[CD-TE-16]`, `[KDD-deploy-1]`

---

### WP-28: Unit Tests — Diff, Collision Detection, Acyclicity

**Description**: Comprehensive unit tests for diff calculation, naming collision detection, and graph acyclicity.

**Acceptance Criteria**:
- **Diff**: Added attribute detected. Removed attribute detected. Changed value detected. Changed alarm trigger detected. Changed script code detected. Unchanged members not reported. (`[CD-TE-12]`)
- **Collision**: Two modules with same attribute name → collision. Module member collides with top-level member → collision. Different module instance names → no collision. Recursive nested collision → detected. (`[3.5-7]`–`[3.5-9]`, `[CD-TE-7]`, `[CD-TE-8]`)
- **Acyclicity**: Self-inheritance → rejected. Circular inheritance (A→B→A) → rejected. Self-composition → rejected. Circular composition → rejected. Cross-graph cycle (inherit + compose) → rejected. Valid DAGs → accepted. (`[CD-TE-17]`–`[CD-TE-19]`)

**Estimated Complexity**: L

**Requirements Traced**: `[CD-TE-12]`, `[3.5-7]`–`[3.5-9]`, `[CD-TE-7]`, `[CD-TE-8]`, `[CD-TE-17]`–`[CD-TE-19]`, `[KDD-deploy-4]`, `[KDD-deploy-12]`

---

### WP-29: Unit Tests — Locking and Override Rules

**Description**: Comprehensive unit tests for locking semantics and override granularity.

**Acceptance Criteria**:
- Parent locks attribute → child override rejected. (`[3.6-3]`)
- Parent unlocked → child locks → grandchild override rejected. (`[3.6-5]`, `[3.6-6]`)
- Downstream cannot unlock a locked member. (`[3.6-6]`)
- Override of fixed field (e.g., attribute Data Type) → rejected. (`[CD-TE-3]`)
- Override of overridable field on unlocked member → accepted. (`[3.6-4]`)
- Composition: composing template overrides locked module member → rejected. (`[3.6-3]`)
- Instance: instance overrides locked attribute → rejected. (`[3.6-3]`)
- Instance: instance adds attribute → rejected. (`[3.8-3]`)
- Instance: instance removes attribute → rejected. (`[3.8-4]`)
- Override piercing: child overrides member in inherited composed module → accepted if unlocked. (`[3.7-3]`)
- Locking uniformity: all locking tests above are repeated for attributes, alarms, AND scripts to verify uniform behavior across all three entity types. (`[3.6-1]`)
- Test: parent locks alarm → child override of alarm priority → rejected.
- Test: parent locks script → child override of script code → rejected.
- Test: parent unlocked alarm → child locks → grandchild override → rejected.

**Estimated Complexity**: M

**Requirements Traced**: `[3.6-1]`–`[3.6-6]`, `[3.6R-3]`, `[3.7-1]`–`[3.7-3]`, `[3.8-2]`–`[3.8-4]`, `[CD-TE-3]`–`[CD-TE-5]`

---

## 6. Test Strategy

### Unit Tests
- **Flattening**: WP-26 — covers single template, multi-level inheritance, composition, nested composition, inheritance + composition, instance overrides, connection binding resolution.
- **Validation**: WP-27 — covers each validation rule with positive and negative cases, including semantic checks and shared script validation.
- **Diff**: WP-28 — covers added/removed/changed detection across all entity types.
- **Collision Detection**: WP-28 — covers same-name detection, canonical name differentiation, recursive nesting.
- **Acyclicity**: WP-28 — covers self-reference, circular chains, cross-graph cycles.
- **Locking and Overrides**: WP-29 — covers lock propagation, intermediate locking, override granularity per entity type/field, instance constraints.
- **CRUD operations**: Each WP includes validation of persistence round-trips.

### Integration Tests
- **Repository integration**: Verify ITemplateEngineRepository operations against a real MS SQL database (test container or Docker test infra).
- **Full pipeline**: Create a complex template tree → flatten → validate → diff → verify all outputs are consistent.
- **Audit logging**: Verify all CRUD operations produce audit log entries in the same transaction.
- **Deletion constraints**: Verify template/area deletion fails when references exist.

### Negative Test Cases (from "cannot", "does not", "not" requirements)
- Templates do NOT specify default connection. (`[3.3-7]`)
- Validation does NOT verify tag paths resolve on devices. (`[3.11-7]`)
- Child CANNOT remove parent members. (`[3.5-4]`)
- Instances CANNOT add attributes. (`[3.8-3]`)
- Instances CANNOT remove attributes. (`[3.8-4]`)
- Locked members CANNOT be overridden. (`[3.6-3]`)
- Downstream CANNOT unlock a locked member. (`[3.6-6]`)
- Template CANNOT be saved with naming collisions. (`[3.5-9]`)
- Template CANNOT be saved with graph cycles. (`[KDD-deploy-4]`)
- Template CANNOT be deleted with references. (`[CD-TE-2]`)
- Changes NOT auto-propagated. (`[3.9-1]`)
- Instance scripts CANNOT call alarm on-trigger scripts. (`[3.4-13]`)

---

## 7. Verification Gate

Phase 2 is considered complete when ALL of the following pass:

1. **All unit tests pass**: WP-26, WP-27, WP-28, WP-29 green.
2. **Integration test suite passes**: Full pipeline test (create → flatten → validate → diff) succeeds.
3. **Complex template tree test**: A template tree with at least 3 levels of inheritance, 2 levels of composition nesting, overrides at each level, locked and unlocked members, and multiple data connection bindings can be flattened, validated, and diffed correctly.
4. **Revision hash determinism**: Same template tree produces identical revision hashes across multiple flattening runs.
5. **Deployment package contract**: Format is defined, documented, serializable, and deserializable. Contract is reviewed and stable.
6. **All negative requirements verified**: Each "cannot"/"does not"/"not" requirement has a passing test that verifies the prohibition.
7. **All validation rules enforced**: Each of the 6 validation checks (flattening, collisions, script compilation, alarm trigger refs, script trigger refs, connection binding) plus all 4 semantic checks (call targets, arg types, return types, trigger operand types) have passing tests.
8. **Audit logging coverage**: All CRUD operations (template, instance, shared script, area, site, data connection) produce audit entries.
9. **No orphan requirements**: Every item in Requirements Checklist and Design Constraints Checklist maps to a work package with acceptance criteria.

---

## 8. Open Questions

| # | Question | Context | Impact | Status |
|---|----------|---------|--------|--------|
| Q-P2-1 | What hashing algorithm should be used for revision hashes? | SHA-256 is the likely choice for determinism and collision resistance, but should be confirmed. | WP-16. Low risk — algorithm can be changed without API impact. | Open — proceed with SHA-256 as default. |
| Q-P2-2 | What serialization format for the deployment package contract? | JSON is most natural for .NET; MessagePack is more compact. Decision affects Site Runtime deserialization. | WP-17. Medium — format must be stable once sites consume it. | Open — recommend JSON for debuggability; can add binary format later. |
| Q-P2-3 | How should script pre-compilation handle references to runtime APIs (GetAttribute, SetAttribute, ExternalSystem.Call, etc.) that don't exist at compile time on central? | Scripts reference runtime APIs that only exist at the site. Central needs stub types/interfaces for compilation. | WP-18, WP-19. Must be addressed before script compilation validation works. | Open — implement compilation against a stub "ScriptApi" assembly that defines the runtime API surface. |
| Q-P2-4 | Should semantic validation for CallShared resolve against the shared script library as it exists at validation time, or against the deployed version at the target site? | Shared scripts may be modified between validation and deployment. | WP-19. Low risk if validation is always re-run before deployment. | Open — validate against current library; document that deployment re-validates. |

These questions are logged in `docs/plans/questions.md`.

---

## 9. Post-Generation Verification (Orphan Check)

### Forward Check (Requirements → Work Packages)

Every item in the Requirements Checklist and Design Constraints Checklist is traced below:

| Requirement | Work Package(s) |
|-------------|----------------|
| `[3.1-1]` | WP-1 |
| `[3.1-2]` | WP-2 |
| `[3.1-3]` | WP-2 |
| `[3.2-1]` | WP-2 |
| `[3.2-2]` | WP-2 |
| `[3.2-3]` | WP-2 |
| `[3.2-4]` | WP-2 |
| `[3.2-5]` | WP-2 |
| `[3.2-6]` | WP-2 |
| `[3.2-7]` | WP-2 |
| `[3.2-8]` | WP-2 |
| `[3.3-1]` | WP-20, WP-21 |
| `[3.3-2]` | WP-21 |
| `[3.3-3]` | WP-20 |
| `[3.3-4]` | WP-20 |
| `[3.3-5]` | WP-20 |
| `[3.3-6]` | WP-20 |
| `[3.3-7]` | WP-2 |
| `[3.3-8]` | WP-14 |
| `[3.3-9]` | WP-21 |
| `[3.4-1]` | WP-3 |
| `[3.4-2]` | WP-3 |
| `[3.4-3]` | WP-3 |
| `[3.4-4]` | WP-3 |
| `[3.4-5]` | WP-3 |
| `[3.4-6]` | WP-3 |
| `[3.4-7]` | WP-3 |
| `[3.4-8]` | WP-3 |
| `[3.4-9]` | WP-3 |
| `[3.4-10]` | WP-3 |
| `[3.4-11]` | WP-3, WP-19 |
| `[3.4-12]` | WP-19 |
| `[3.4-13]` | WP-19 |
| `[3.5-1]` | WP-1, WP-6 |
| `[3.5-2]` | WP-10 |
| `[3.5-3]` | WP-10 |
| `[3.5-4]` | WP-10 |
| `[3.5-5]` | WP-6 |
| `[3.5-6]` | WP-6 |
| `[3.5-7]` | WP-12 |
| `[3.5-8]` | WP-12 |
| `[3.5-9]` | WP-12 |
| `[3.6-1]` | WP-2, WP-9 |
| `[3.6-2]` | WP-2, WP-9 |
| `[3.6-3]` | WP-8, WP-9 |
| `[3.6-4]` | WP-9 |
| `[3.6-5]` | WP-9 |
| `[3.6-6]` | WP-9 |
| `[3.6R-1]` | WP-14 |
| `[3.6R-2]` | WP-14 |
| `[3.6R-3]` | WP-9 |
| `[3.7-1]` | WP-10 |
| `[3.7-2]` | WP-11 |
| `[3.7-3]` | WP-10 |
| `[3.8-1]` | WP-20 |
| `[3.8-2]` | WP-20 |
| `[3.8-3]` | WP-20 |
| `[3.8-4]` | WP-20 |
| `[3.8-5]` | WP-20 |
| `[3.8-6]` | WP-20 |
| `[3.9-1]` | WP-15 |
| `[3.9-2]` | WP-15 |
| `[3.9-3]` | WP-15 |
| `[3.9-4]` | WP-15 |
| `[3.9-5]` | WP-1 |
| `[3.9-6]` | WP-20 (data model), Phase 3C (pipeline execution) |
| `[3.10-1]` | WP-22 |
| `[3.10-2]` | WP-22 |
| `[3.10-3]` | WP-22 |
| `[3.10-4]` | WP-20, WP-22 |
| `[3.10-5]` | Phase 4 (UI filtering) |
| `[3.10-6]` | Phase 4 (Admin role enforcement in UI) |
| `[3.11-1]` | WP-14, WP-18 |
| `[3.11-2]` | WP-18 |
| `[3.11-3]` | WP-18 |
| `[3.11-4]` | WP-18 |
| `[3.11-5]` | WP-18 |
| `[3.11-6]` | WP-18 |
| `[3.11-7]` | WP-18 |
| `[3.11-8]` | WP-18 |
| `[3.11-9]` | WP-5 |
| `[4.1-1]` | WP-4 |
| `[4.1-2]` | WP-4 |
| `[4.1-3]` | WP-4, WP-17 |
| `[4.1-4]` | WP-17 |
| `[4.1-5]` | WP-4 |
| `[4.1-6]` | WP-4 |
| `[4.1-7]` | WP-17 |
| `[4.5-1]` | WP-5 |
| `[4.5-2]` | WP-5 |
| `[4.5-3]` | WP-5 |
| `[KDD-deploy-1]` | WP-19 |
| `[KDD-deploy-2]` | WP-6, WP-7 |
| `[KDD-deploy-3]` | WP-8 |
| `[KDD-deploy-4]` | WP-13 |
| `[KDD-deploy-5]` | WP-16, WP-17 |
| `[KDD-deploy-10]` | WP-1 |
| `[KDD-deploy-12]` | WP-12 |
| `[CD-TE-1]` | WP-1 |
| `[CD-TE-2]` | WP-1, WP-25 |
| `[CD-TE-3]` | WP-8 |
| `[CD-TE-4]` | WP-8 |
| `[CD-TE-5]` | WP-8 |
| `[CD-TE-6]` | WP-8, WP-11 |
| `[CD-TE-7]` | WP-12 |
| `[CD-TE-8]` | WP-12 |
| `[CD-TE-9]` | WP-7 |
| `[CD-TE-10]` | WP-7 |
| `[CD-TE-11]` | WP-14 |
| `[CD-TE-12]` | WP-15 |
| `[CD-TE-13]` | WP-19 |
| `[CD-TE-14]` | WP-19 |
| `[CD-TE-15]` | WP-19 |
| `[CD-TE-16]` | WP-19 |
| `[CD-TE-17]` | WP-13 |
| `[CD-TE-18]` | WP-13 |
| `[CD-TE-19]` | WP-13 |
| `[CD-TE-20]` | WP-16 |
| `[CD-TE-21]` | WP-18 |
| `[CD-TE-22]` | WP-5 |
| `[CD-TE-23]` | WP-20 |
| `[CD-TE-24]` | WP-20 |
| `[CD-TE-25]` | WP-4 |
| `[CD-TE-26]` | WP-4 |
| `[CD-CDB-1]` | WP-6, WP-20, WP-21, WP-22, WP-23 |
| `[CD-CDB-2]` | WP-24 |
| `[CD-CDB-3]` | WP-1 |
| `[CD-CDB-4]` | WP-20 (instance lifecycle state), WP-24 (deployment status) |
| `[CD-CDB-5]` | WP-23 |
| `[CD-CDB-6]` | WP-23 |
| `[CD-CDB-7]` | WP-5 |
| `[CD-CDB-8]` | WP-21 |
| `[CD-CDB-9]` | WP-21 |

**Result**: All 110 requirements and design constraints map to at least one work package (including 3 bullets deferred to other phases but extracted for traceability: `[3.9-6]`, `[3.10-5]`, `[3.10-6]`). **No orphans.**

### Reverse Check (Work Packages → Requirements)

Every work package traces to at least one requirement or design constraint:

| Work Package | Traced Requirements |
|-------------|-------------------|
| WP-1 | `[3.1-1]`, `[3.5-1]`, `[3.9-5]`, `[CD-TE-1]`, `[CD-TE-2]`, `[KDD-deploy-10]`, `[CD-CDB-1]`, `[CD-CDB-3]` |
| WP-2 | `[3.1-2]`, `[3.1-3]`, `[3.2-1]`–`[3.2-8]`, `[3.3-7]`, `[3.6-1]`, `[3.6-2]` |
| WP-3 | `[3.4-1]`–`[3.4-11]` |
| WP-4 | `[4.1-1]`–`[4.1-6]`, `[CD-TE-25]`, `[CD-TE-26]` |
| WP-5 | `[4.5-1]`–`[4.5-3]`, `[3.11-9]`, `[CD-TE-22]`, `[CD-CDB-7]` |
| WP-6 | `[3.5-1]`, `[3.5-5]`, `[3.5-6]`, `[KDD-deploy-2]`, `[CD-CDB-1]` |
| WP-7 | `[KDD-deploy-2]`, `[CD-TE-9]`, `[CD-TE-10]` |
| WP-8 | `[KDD-deploy-3]`, `[CD-TE-3]`–`[CD-TE-6]`, `[3.6-3]` |
| WP-9 | `[3.6-1]`–`[3.6-6]`, `[3.6R-3]` |
| WP-10 | `[3.5-2]`–`[3.5-4]`, `[3.7-1]`, `[3.7-3]` |
| WP-11 | `[3.7-2]`, `[CD-TE-6]` |
| WP-12 | `[3.5-7]`–`[3.5-9]`, `[KDD-deploy-12]`, `[CD-TE-7]`, `[CD-TE-8]` |
| WP-13 | `[KDD-deploy-4]`, `[CD-TE-17]`–`[CD-TE-19]` |
| WP-14 | `[3.6R-1]`, `[3.6R-2]`, `[3.3-8]`, `[3.11-1]`, `[CD-TE-11]` |
| WP-15 | `[3.9-1]`–`[3.9-4]`, `[CD-TE-12]` |
| WP-16 | `[KDD-deploy-5]`, `[CD-TE-20]` |
| WP-17 | `[4.1-3]`, `[4.1-4]`, `[4.1-7]`, `[KDD-deploy-5]` |
| WP-18 | `[3.11-1]`–`[3.11-8]`, `[CD-TE-21]` |
| WP-19 | `[KDD-deploy-1]`, `[CD-TE-13]`–`[CD-TE-16]`, `[3.4-11]`–`[3.4-13]` |
| WP-20 | `[3.8-1]`–`[3.8-6]`, `[3.9-6]`, `[3.10-4]`, `[3.3-1]`, `[3.3-3]`–`[3.3-6]`, `[CD-TE-23]`, `[CD-TE-24]`, `[CD-CDB-1]`, `[CD-CDB-4]` |
| WP-21 | `[3.3-1]`, `[3.3-2]`, `[3.3-9]`, `[CD-CDB-8]`, `[CD-CDB-9]`, `[CD-CDB-1]` |
| WP-22 | `[3.10-1]`–`[3.10-4]`, `[CD-CDB-1]` |
| WP-23 | `[CD-CDB-1]`, `[CD-CDB-5]`, `[CD-CDB-6]` |
| WP-24 | `[CD-CDB-2]`, `[CD-CDB-4]` |
| WP-25 | `[CD-TE-2]` |
| WP-26 | All WP-14 requirements (test coverage) |
| WP-27 | `[3.11-1]`–`[3.11-9]`, `[CD-TE-13]`–`[CD-TE-16]`, `[KDD-deploy-1]` (test coverage) |
| WP-28 | `[CD-TE-12]`, `[3.5-7]`–`[3.5-9]`, `[CD-TE-7]`, `[CD-TE-8]`, `[CD-TE-17]`–`[CD-TE-19]`, `[KDD-deploy-4]`, `[KDD-deploy-12]` (test coverage) |
| WP-29 | `[3.6-1]`–`[3.6-6]`, `[3.6R-3]`, `[3.7-1]`–`[3.7-3]`, `[3.8-2]`–`[3.8-4]`, `[CD-TE-3]`–`[CD-TE-5]` (test coverage) |

**Result**: All 29 work packages trace to requirements. **No untraceable work.**

### Split-Section Check

| Section | Phase 2 Bullets | Other Phase Bullets | Verified |
|---------|----------------|--------------------|---------|
| 3.3 Data Connections | `[3.3-1]`–`[3.3-9]` (model, binding, flattened config resolution) | Phase 3B: runtime protocol adapters, subscription, auto-reconnect, write-back, tag path resolution | Complete — Phase 2 covers all 3.3 bullets from the modeling/binding perspective. Runtime behavior in Phase 3B adds no new 3.3 bullets; it implements the runtime for the same connections. |
| 3.9 Template Deployment | `[3.9-1]`–`[3.9-6]` (diff, two views, last-write-wins, no rollback, per-instance deployment model) | Phase 3C: `[3.9-6]` pipeline execution. Phase 6: deployment UI. | Complete — Phase 2 extracts all bullets. `[3.9-6]` data model in Phase 2, pipeline execution in Phase 3C. |
| 3.10 Areas | `[3.10-1]`–`[3.10-6]` (model, hierarchy, storage, filtering, Admin role) | Phase 4: `[3.10-5]` UI filtering, `[3.10-6]` Admin role enforcement in UI. | Complete — Phase 2 covers `[3.10-1]`–`[3.10-4]` data model. Phase 4 covers `[3.10-5]`, `[3.10-6]`. |
| 4.1 Script Definitions | `[4.1-1]`–`[4.1-7]` (model, inheritance, parameters, return values, pre-compilation) | Phase 3B: script triggers (interval, value change, conditional), minimum time between runs (runtime enforcement), Script Actors, Script Execution Actors, runtime compilation. | Complete — Phase 2 covers all model-level 4.1 bullets. Phase 3B adds runtime execution. |
| 4.5 Shared Scripts | `[4.5-1]`–`[4.5-3]` (model, parameters, Design role) | Phase 3B: deployment to sites, inline execution, not available on central. | Complete — Phase 2 covers model. Phase 3B covers runtime (`[4.5-4]` deployment, `[4.5-5]` inline execution, `[4.5-6]` not on central). |

**Result**: All split sections have complete bullet coverage between Phase 2 and their partner phases. **No gaps.**

### Negative Requirement Check

| Negative Requirement | Acceptance Criterion | Work Package |
|---------------------|---------------------|-------------|
| Templates do NOT specify default connection (`[3.3-7]`) | Attribute definition has no default connection field; template has no connection property. | WP-2 |
| Validation does NOT verify tag paths on devices (`[3.11-7]`) | Test: arbitrary paths pass validation. | WP-18, WP-27 |
| Child CANNOT remove parent members (`[3.5-4]`) | Test: removal attempt → rejected. | WP-10, WP-29 |
| Instances CANNOT add attributes (`[3.8-3]`) | Test: add attempt → rejected. | WP-20, WP-29 |
| Instances CANNOT remove attributes (`[3.8-4]`) | Test: remove attempt → rejected. | WP-20, WP-29 |
| Locked members CANNOT be overridden (`[3.6-3]`) | Test: override locked → rejected. | WP-9, WP-29 |
| Downstream CANNOT unlock (`[3.6-6]`) | Test: unlock attempt → rejected. | WP-9, WP-29 |
| Template CANNOT be saved with collisions (`[3.5-9]`) | Test: save with collision → rejected. | WP-12, WP-28 |
| Template CANNOT be saved with cycles (`[KDD-deploy-4]`) | Test: cyclic graph → rejected on save. | WP-13, WP-28 |
| Template CANNOT be deleted with references (`[CD-TE-2]`) | Test: delete referenced → rejected. | WP-25 |
| Changes NOT auto-propagated (`[3.9-1]`) | Diff exists but deployed config unchanged until explicit deploy. | WP-15 |
| Instance scripts CANNOT call alarm on-trigger scripts (`[3.4-13]`) | Semantic validation: CallScript to alarm on-trigger script → error. | WP-19, WP-27 |
| No rollback (`[3.9-4]`) | No rollback API or operation exposed. Deployment history exists for audit, but no mechanism to revert. Test: no rollback endpoint or method exists. | WP-15, WP-24 |

**Result**: All 13 negative requirements have explicit acceptance criteria that test the prohibition. **No weak verifications.**

---

## Codex MCP Verification

Codex MCP external verification was performed using model `gpt-5.4`. The review identified 15 findings.

### Step 1 — Requirements Coverage Review

**Findings addressed (corrections applied to the plan)**:
1. **Area filtering and Admin role bullets not extracted** — Added `[3.10-5]` and `[3.10-6]` to Requirements Checklist with Phase 4 ownership noted. Split-section check updated.
2. **3.9 individual-instance deployment bullet not extracted** — Added `[3.9-6]` to Requirements Checklist. Split-section check updated.
3. **System-wide artifact deployment status in WP-24** — WP-24 is a stub; system-wide artifact deployment status is Phase 3C scope. Accepted as-is (stub level sufficient for Phase 2).
4. **Instance lifecycle concurrency missing from WP-20** — Added optimistic concurrency via rowversion to WP-20 acceptance criteria. Updated `[CD-CDB-4]` forward trace.
5. **Shared scripts repository assignment** — Clarified in WP-5 and WP-23 that shared scripts may use ITemplateEngineRepository or a separate interface; the docs/requirements/Component-ConfigurationDatabase.md ITemplateEngineRepository scope does not explicitly include shared scripts.
6. **"No rollback" vs deployment history records** — Clarified in WP-15 and `[3.9-4]` that "no rollback" means no rollback mechanism/operation, not absence of deployment history records. Deployment records exist for audit per Configuration Database schema.
7. **Composition deletion constraint in WP-25** — Added clarifying note that composed-template deletion constraint is a logical implication of `[CD-TE-2]` (stricter but consistent interpretation).

### Step 2 — Negative Requirement Review

**Findings addressed**:
8. **`[4.1-7]` discard-on-trigger not verified** — Added explicit acceptance criterion to WP-17.
9. **`[3.3-9]` non-standardized names weakly verified** — Added explicit test criterion to WP-21.
10. **`[3.6-1]` locking tests only attribute-centric** — Added explicit alarm and script locking tests to WP-29.
11. **"No rollback" negative test too weak** — Strengthened to verify no rollback API/operation exists.

**Findings accepted without correction (dismissed)**:
12. **`[3.11-8]` Central UI / Design role not verified in WP-18** — Dismissed. Phase 2 provides the on-demand validation API. The Central UI integration and Design role enforcement for the validation UI are Phase 5 concerns. WP-18 correctly verifies the pipeline can be invoked without deployment; UI wiring is out of scope.
13. **`[4.5-3]` Design role gating** — Partially addressed: added Design role enforcement note to WP-5. Full UI-level role enforcement is Phase 5.
14. **`[CD-TE-9]` stream topics and UI display not verified** — Dismissed. Stream topics are Phase 3B (Akka stream); UI display is Phase 5. Phase 2 covers canonical names in triggers, scripts, and diffs which are the Phase 2 concern.
15. **Naming collision with canonical names contradicts HLR** — Dismissed. The HighLevelReqs statement "two feature modules that each define an attribute with the same name" is refined by docs/requirements/Component-TemplateEngine.md which introduces canonical naming with module instance name prefixes. The component design is authoritative for implementation details; the HLR describes the user-facing intent (collisions are errors) while the component design specifies the mechanism (canonical names prevent false collisions). No contradiction — the component design is a refinement.

**Status**: Pass with corrections. All findings either addressed in the plan or dismissed with rationale.
