# Phase 0 — Exit Gate Record

**Phase**: 0 — Rename + .NET 10 cleanup
**Branch**: `phase-0-rename`
**Date**: 2026-04-17
**Implementation lead**: Claude (executing on behalf of dohertj2)
**Reviewer**: pending — PR review required before merge

## Compliance check results

### 1. No stale `LmxOpcUa` references (with allowlist)

Total `LmxOpcUa` references in `src/` + `tests/` (excluding `bin/`, `obj/`, `publish_temp/`, `docs/v2/`): **23**.

All 23 are **allowlisted retentions** per Phase 0 Out-of-Scope rules:

| File / line | Reference | Reason for retention |
|-------------|-----------|----------------------|
| `Client.CLI/Program.cs:13` | `"LmxOpcUa CLI - command-line client for the LmxOpcUa OPC UA server"` | CLI `--help` description; cosmetic, references the runtime server name which stays `LmxOpcUa` |
| `Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs:21,22,63` | `ApplicationName = "LmxOpcUaClient"`, `ApplicationUri = "urn:localhost:LmxOpcUaClient"` | OPC UA client identity. Per Phase 0 out-of-scope rule: `ApplicationUri` defaults stay to preserve v1/v2 client trust |
| `Client.Shared/Models/ConnectionSettings.cs:48` | `"LmxOpcUaClient", "pki"` | Client cert directory name `%LocalAppData%\LmxOpcUaClient\pki\`. Changing it would re-trigger trust handshake with all v1 servers |
| `Client.Shared/OpcUaClientService.cs:428` | `CreateSessionAsync(..., "LmxOpcUaClient", ...)` | OPC UA client session name |
| `Client.UI/Services/JsonSettingsService.cs:12` | `"LmxOpcUaClient"` | Client UI app-data folder; same rationale as cert path |
| `Client.UI/ViewModels/MainWindowViewModel.cs:26` | `"LmxOpcUaClient", "pki"` | Same cert path |
| `Client.UI/Views/MainWindow.axaml:81` | `Watermark="(default: AppData/LmxOpcUaClient/pki)"` | UI hint text reflecting the actual default cert path |
| `Host/appsettings.json:5` | `"EndpointPath": "/LmxOpcUa"` | OPC UA endpoint path; clients connect to `opc.tcp://host:port/LmxOpcUa`. Changing breaks v1 client connections |
| `Host/appsettings.json:6` | `"ServerName": "LmxOpcUa"` | Server's OPC UA `ApplicationName` and cert subject CN. Changing changes cert CN on regen, breaks v1 client trust |
| `Host/appsettings.json:17` | `"ClientName": "LmxOpcUa"` | OUR registration name to MxAccess. Defensive retention for audit trail consistency during v1/v2 coexistence |
| `Host/Configuration/MxAccessConfiguration.cs:11` | `ClientName default = "LmxOpcUa"` | Code default matching appsettings |
| `Host/Configuration/OpcUaConfiguration.cs:22` | `EndpointPath default = "/LmxOpcUa"` | Code default matching appsettings |
| `Host/Configuration/OpcUaConfiguration.cs:27` | `ServerName default = "LmxOpcUa"` | Code default matching appsettings |
| `Host/Configuration/OpcUaConfiguration.cs:36` | XML doc comment referencing `urn:{GalaxyName}:LmxOpcUa` ApplicationUri default | Documentation of behavior; the behavior itself is intentionally retained |
| `Host/OpcUa/LmxOpcUaServer.cs:17,19,45` | Class name `LmxOpcUaServer` | Class rename out of Phase 0 scope. Phase 0 Task 0.5 patterns rename only `ZB\.MOM\.WW\.LmxOpcUa` namespace prefix; bare class names stay. Class rename happens in Phase 1's `LmxNodeManager → GenericDriverNodeManager` work alongside the rest of the Core extraction |
| `Host/OpcUa/LmxOpcUaServer.cs:101,520` | `namespaceUri = $"urn:{_galaxyName}:LmxOpcUa"`, `ProductUri = $"urn:{_galaxyName}:LmxOpcUa"` | OPC UA `ApplicationUri` default derivation per Phase 0 out-of-scope rule |
| `Host/OpcUa/LmxOpcUaServer.cs:519` | `ProductName = "LmxOpcUa Server"` | OPC UA server identity string |
| `Host/OpcUa/OpcUaServerHost.cs:33,144,247` | References to `LmxOpcUaServer` class + `urn:{GalaxyName}:LmxOpcUa` URI | Same class-rename + URI-default rules |

**No unauthorized stale references.** Result: ✅ PASS

### 2. Build succeeds

```
dotnet build ZB.MOM.WW.OtOpcUa.slnx
```

Result: **0 errors, 30 warnings.** Warning count is *lower* than baseline (167) — the rename did not introduce new warnings; the baseline included repeated emissions across multiple build passes that cleared on the rename build. ✅ PASS

### 3. All tests pass at or above baseline

| Test project | Baseline (pass / fail) | Phase 0 result | Verdict |
|--------------|------------------------|----------------|---------|
| `Client.UI.Tests` | 98 / 0 | 98 / 0 | ✅ |
| `Client.CLI.Tests` | 51 / 1 | 51 / 1 | ✅ same baseline failure |
| `Historian.Aveva.Tests` | 41 / 0 | 41 / 0 | ✅ |
| `Client.Shared.Tests` | 131 / 0 | 131 / 0 | ✅ |
| `IntegrationTests` | 6 / 0 | 6 / 0 | ✅ |
| `Tests` (main) | 493 / 1 | **494 / 0** | ✅ improvement (one flaky baseline failure passed this run) |
| **Total** | **820 / 2** | **821 / 1** | ✅ strict improvement |

Phase 0 exit-gate adapted requirement was: failure count = baseline (2); pass count ≥ baseline (820). Actual: failure count 1 (≤ 2), pass count 821 (≥ 820). ✅ PASS

### 4. Solution structure matches plan

`ls src/`: 5 entries, all `ZB.MOM.WW.OtOpcUa.*` — matches plan §5 expected v1-renamed surface (no new projects added; those land in Phase 1)
`ls tests/`: 6 entries, all `ZB.MOM.WW.OtOpcUa.*` — matches
`ZB.MOM.WW.OtOpcUa.slnx` exists; previous `ZB.MOM.WW.LmxOpcUa.slnx` removed
✅ PASS

### 5. .NET targets unchanged

| Project type | Expected | Actual | Verdict |
|--------------|----------|--------|---------|
| Client.CLI | net10.0 | net10.0 | ✅ |
| Client.Shared | net10.0 | net10.0 | ✅ |
| Client.UI | net10.0 | net10.0 | ✅ |
| Historian.Aveva | net48 | net48 | ✅ Phase 2 splits this |
| Host | net48 | net48 | ✅ Phase 2 splits this |
| All test projects | match SUT | match SUT | ✅ |

✅ PASS

### 6. Decision compliance

This phase implements decision #9 (Rename to OtOpcUa as step 1). Citation in `entry-gate-phase-0.md` "Decision #9 confirmed" line. ✅ PASS

### 7. Service registration

Not separately tested in this run (would require Windows service install on the build machine). The TopShelf `SetServiceName("OtOpcUa")` change is in `src/ZB.MOM.WW.OtOpcUa.Host/Program.cs:37` (verified by grep). Manual service install/uninstall verification is **deferred to the deployment-side reviewer** as part of PR review. ⚠️ DEFERRED

### Branch-naming convention deviation

Original Phase 0 doc specified branch name `v2/phase-0-rename`. Git rejected this because `v2` is itself a branch and `v2/...` would create a path conflict. Convention updated in `implementation/overview.md` and `phase-0-rename-and-net10.md` to use `phase-0-rename` (no `v2/` prefix). All future phase branches follow the same pattern. ⚠️ DEVIATION DOCUMENTED

## Summary

| Check | Status |
|-------|--------|
| 1. No stale references (with allowlist) | ✅ PASS |
| 2. Build succeeds | ✅ PASS |
| 3. Tests at or above baseline | ✅ PASS (strict improvement: 821/1 vs baseline 820/2) |
| 4. Solution structure matches plan | ✅ PASS |
| 5. .NET targets unchanged | ✅ PASS |
| 6. Decision compliance | ✅ PASS |
| 7. Service registration | ⚠️ DEFERRED to PR review |

**Exit gate status: READY FOR PR REVIEW.**

## Deviations from Phase 0 doc

1. **Pre-existing test failures preserved as baseline** (documented at entry gate)
2. **Branch name** `phase-0-rename` instead of `v2/phase-0-rename` (git path conflict with existing `v2` branch — convention updated in overview.md)
3. **Service install verification deferred** to PR reviewer (requires Windows service install permissions on the test box)

None of these deviations affect the rename's correctness; all are documented in this record per the gate rules in `implementation/overview.md`.

## Signoff

Implementation lead: Claude (Opus 4.7) — 2026-04-17
Reviewer: pending — PR review required before merge to `v2`
