288 lines
17 KiB
Markdown
288 lines
17 KiB
Markdown
# Management Actor, API, and CLI parity review
|
||
|
||
**Date:** 2026-09-10
|
||
**Reviewed revision:** `9ee402bb`
|
||
**Status:** Completed — all GAP-01–GAP-07 and PAR-01–PAR-05 resolved, merged into `main`, and verified locally.
|
||
|
||
## Original review scope and method
|
||
|
||
Source-level comparison of management command records, automatic HTTP command
|
||
registration, ManagementActor dispatch (including inherited record types), CLI
|
||
command construction and registration, and management audit REST endpoints.
|
||
No live mutations were performed and no tests were rerun for this review.
|
||
|
||
At the reviewed revision, 19 registered command groups and the passing 475-test
|
||
suite did not establish complete actor/API parity. The baseline inventory found:
|
||
|
||
| Inventory | Count |
|
||
|---|---:|
|
||
| Registered management command contracts | 151 |
|
||
| Contracts handled by ManagementActor, including inherited commands | 149 |
|
||
| Registered contracts referenced in CLI command source | 130 |
|
||
| Handled contracts without a direct CLI mapping | 19 |
|
||
| Registered contracts without an actor dispatch handler | 2 |
|
||
|
||
The 130 figure measures source references, not independently verified end-to-end
|
||
behavior or complete option coverage. The four audit REST endpoints (query,
|
||
export, tree, and backfill-source-node) have CLI counterparts. The internal
|
||
deployment-configuration fetch endpoint is machine-to-machine infrastructure and
|
||
is not counted as a missing operator command.
|
||
|
||
## Missing CLI operations
|
||
|
||
All 19 commands below are handled by the actor and reachable through the generic
|
||
`POST /management` API, subject to server-side authorization. Remediation adds
|
||
all 19, including the full secured-write lifecycle. The descriptions below retain
|
||
the original findings; status cells and completion evidence track the fixes.
|
||
|
||
| ID | Capability | Missing command contracts | Status |
|
||
|---|---|---|---|
|
||
| GAP-01 | Shared-schema library (5) | `ListSharedSchemasCommand`, `GetSharedSchemaCommand`, `CreateSharedSchemaCommand`, `UpdateSharedSchemaCommand`, `DeleteSharedSchemaCommand` | Completed |
|
||
| GAP-02 | Secured-write lifecycle (3) | `SubmitSecuredWriteCommand`, `ApproveSecuredWriteCommand`, `RejectSecuredWriteCommand` | Completed; full lifecycle exposed |
|
||
| GAP-03 | Individual notification editing (3) | `RenameNotificationListCommand`, `AddNotificationRecipientCommand`, `DeleteNotificationRecipientCommand` | Completed |
|
||
| GAP-04 | Provider configuration creation (2) | `CreateSmtpConfigCommand`, `CreateSmsConfigCommand` | Completed |
|
||
| GAP-05 | Template inspection and editing (3) | `GetResolvedTemplateMembersCommand`, `MoveTemplateToFolderCommand`, `UpdateTemplateNativeAlarmSourceCommand` | Completed |
|
||
| GAP-06 | Instance override management (2) | `DeleteInstanceAttributeOverrideCommand`, `ListInstanceNativeAlarmSourceOverridesCommand` | Completed |
|
||
| GAP-07 | Data-connection relocation (1) | `MoveDataConnectionCommand` | Completed |
|
||
|
||
Evidence:
|
||
|
||
- [ManagementActor dispatch](../../src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs)
|
||
- [CLI root registration](../../src/ZB.MOM.WW.ScadaBridge.CLI/CliApplication.cs)
|
||
- [CLI command implementations](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/)
|
||
- [Management command contracts](../../src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/)
|
||
|
||
`CreateSmtpConfigCommand` and `CreateSmsConfigCommand` inherit their update
|
||
contracts and are dispatched through the corresponding update handlers. They
|
||
are not unhandled API contracts. The handlers distinguish the create subtype;
|
||
sending an ordinary update with ID zero is not equivalent.
|
||
|
||
## Original behavioral and contract findings
|
||
|
||
Severity is a review estimate. These findings overlap the operation inventory;
|
||
do not add the row counts together as unique missing commands.
|
||
|
||
### PAR-01 — Deployment deadlines differ between API and CLI
|
||
|
||
**Severity:** Medium · **Status:** Completed
|
||
|
||
`deploy instance`, `instance deploy`, `deploy artifacts`, and
|
||
`site deploy-artifacts` use the default 30-second CLI request deadline. The API
|
||
classifies their contracts as long-running and allows five minutes by default.
|
||
The CLI can report a timeout while the deployment continues, encouraging a
|
||
retry of work that is still applying. `deploy site` already avoids a shorter
|
||
client deadline by allowing the server to own the overall time budget.
|
||
|
||
**Recommended resolution:** Align these commands with the server-owned deadline
|
||
policy and add delayed-response regression coverage for every CLI alias.
|
||
|
||
**Evidence:** [CommandHelpers](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/CommandHelpers.cs),
|
||
[DeployCommands](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/DeployCommands.cs),
|
||
[InstanceCommands](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/InstanceCommands.cs),
|
||
[SiteCommands](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/SiteCommands.cs),
|
||
[ManagementEndpoints](../../src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementEndpoints.cs).
|
||
|
||
### PAR-02 — Notification replacement is not equivalent to individual editing
|
||
|
||
**Severity:** Medium · **Status:** Completed · **Related:** GAP-03
|
||
|
||
The existing CLI whole-list update reaches `HandleUpdateNotificationList`, which
|
||
deletes existing recipients and recreates them. It cannot faithfully replace
|
||
rename-only or individual-recipient editing while preserving recipient IDs and
|
||
names. The actor already provides dedicated commands for those operations.
|
||
|
||
**Recommended resolution:** Expose rename and recipient add/delete commands and
|
||
verify unrelated recipients retain their identities and names.
|
||
|
||
**Evidence:** [NotificationCommands](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/NotificationCommands.cs),
|
||
[ManagementActor.HandleUpdateNotificationList](../../src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs).
|
||
|
||
### PAR-03 — SMS retry and timeout options are missing
|
||
|
||
**Severity:** Low · **Status:** Completed
|
||
|
||
The actor/API accept `ConnectionTimeoutSeconds`, `MaxRetries`, and `RetryDelay`
|
||
on `UpdateSmsConfigCommand`. CLI payload construction supplies none of these
|
||
fields, so scripts cannot configure them through `notification sms update`.
|
||
Omitted values preserve stored settings; this is a capability gap, not evidence
|
||
that normal CLI updates reset these settings.
|
||
|
||
**Recommended resolution:** Add corresponding optional CLI flags and verify
|
||
explicit values and omission behavior against the API contract.
|
||
|
||
**Evidence:** [CLI NotificationCommands](../../src/ZB.MOM.WW.ScadaBridge.CLI/Commands/NotificationCommands.cs),
|
||
[notification contracts](../../src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/NotificationCommands.cs),
|
||
[ManagementActor.HandleUpdateSmsConfig](../../src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs).
|
||
|
||
### PAR-04 — Registry accepts two contracts the actor cannot dispatch
|
||
|
||
**Severity:** Low · **Status:** Completed
|
||
|
||
The registry automatically includes every concrete `*Command` type in the
|
||
management namespace. `ReadTagValuesCommand` and `ResolveRolesCommand` therefore
|
||
resolve at the HTTP boundary but have no ManagementActor dispatch handler.
|
||
|
||
- `ReadTagValuesCommand` is used by the UI's binding tester, which routes directly
|
||
to a site. There is no corresponding management handler or CLI operation.
|
||
Its existing contract lacks the site identifier needed for central routing.
|
||
- `ResolveRolesCommand` is intentionally retired: the HTTP endpoint authenticates
|
||
and resolves roles before dispatch. Restoring the old handler is not the fix.
|
||
|
||
**Recommended resolution:** Make HTTP eligibility explicit. Exclude retired or
|
||
site-only contracts, or add a separately authorized, site-scoped management
|
||
operation where operator access is desired. Preserve the retired role-resolution
|
||
flow's security restriction.
|
||
|
||
**Evidence:** [ManagementCommandRegistry](../../src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/ManagementCommandRegistry.cs),
|
||
[ManagementActor](../../src/ZB.MOM.WW.ScadaBridge.ManagementService/ManagementActor.cs),
|
||
[ReadTagValuesCommand](../../src/ZB.MOM.WW.ScadaBridge.Commons/Messages/Management/ReadTagValuesCommand.cs),
|
||
[BindingTester](../../src/ZB.MOM.WW.ScadaBridge.CentralUI/Services/BindingTester.cs).
|
||
|
||
### PAR-05 — Tests do not enforce complete surface parity
|
||
|
||
**Severity:** Low · **Status:** Completed
|
||
|
||
Command-tree tests verify existing groups and selected operations, but do not
|
||
require every supported actor command to map to a CLI command or an explicit
|
||
exemption. The current passing suite can coexist with the gaps above.
|
||
|
||
**Recommended resolution:** Maintain a checked command-to-CLI mapping with
|
||
documented exemptions. Verify registry-to-dispatch coverage, account for record
|
||
inheritance, and test representative payload fields and deadline policies.
|
||
|
||
**Evidence:** [CommandTreeTests](../../tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/CommandTreeTests.cs),
|
||
[ManagementCommandRegistryTests](../../tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Messages/ManagementCommandRegistryTests.cs).
|
||
|
||
## Suggested order
|
||
|
||
1. Fix deployment deadline parity and expose non-replacing notification edits.
|
||
2. Add the missing schema, configuration, template, instance, and connection operations.
|
||
3. Decide whether secured-write CLI scope should expand; retain an explicit exemption if not.
|
||
4. Correct HTTP registry eligibility and add SMS options.
|
||
5. Add a parity gate so subsequent actor/API additions require CLI support or a recorded exemption.
|
||
|
||
This is a bounded surface comparison, not an exhaustive security audit or a
|
||
field-by-field review of all 130 CLI-referenced contracts.
|
||
|
||
|
||
## Implementation plan and progress
|
||
|
||
The requested remediation implements all 19 CLI mappings, including secured-write
|
||
submit/approve/reject through existing server authorization. The HTTP registry
|
||
will exclude site-only ReadTagValues and retired ResolveRoles contracts; their
|
||
internal types remain intact. Existing update semantics remain compatible.
|
||
|
||
| Work package | Files / scope | Verification | Status |
|
||
|---|---|---|---|
|
||
| Notifications | CLI NotificationCommands; focused notification tests; GAP-03/04, PAR-02/03 | Capture real command payloads, preserve named recipients, create and optional SMS settings | Completed |
|
||
| Template/instance/connection commands | CLI TemplateCommands, InstanceCommands, DataConnectionCommands; GAP-05/06/07 | Parse and HTTP-envelope regressions for every added operation | Completed |
|
||
| Schema and secured writes | New SharedSchemaCommands, SecuredWriteCommands; GAP-01/02 | Real command payloads, role enforcement remains server-side | Completed |
|
||
| Deadline and registry policy | CommandHelpers, Commons registry, API tests; PAR-01/04 | Delayed responses for all deploy aliases; rejected HTTP-ineligible contracts | Completed |
|
||
| Parity gate and integration | CLI root, command mapping tests, CLI docs; PAR-05 | Exhaustive registry/dispatch/CLI mapping with explicit internal exclusions | Completed |
|
||
| Completion | Full solution build/tests, local deployment/read-only smoke, report updates, merge/commit/push | Verification and delivery evidence recorded below | Completed |
|
||
|
||
Each package follows failing regression tests, minimal implementation, focused
|
||
verification, and code review. Builds/tests use a shared lock in this worktree to
|
||
avoid concurrent dotnet output races. The final merge and git operations are
|
||
owned by the primary agent.
|
||
|
||
### Progress checkpoint
|
||
|
||
- Notification/Smtp/Sms focused suite: 52 passed, including 19 new parse/HTTP cases.
|
||
- Editing parity: 15 passed, covering all six added operations and an existing alias.
|
||
- Deployment deadline regression: all four aliases now accept the server's response
|
||
after 31 seconds; the same test failed with the old 30-second client deadline.
|
||
- HTTP registry regressions: 11 passed; ReadTagValues and ResolveRoles no longer resolve.
|
||
- Production-root parity probe: all 149 HTTP-eligible contracts actually dispatched
|
||
to a loopback recorder. Removing the schema group produces missing coverage.
|
||
- Independent review approved the editing and notification mappings. Additional
|
||
actor preservation coverage and secured-write execution-failure exit handling
|
||
are being verified before final completion.
|
||
|
||
|
||
### Independent review follow-ups
|
||
|
||
- Added email and SMS actor-dispatch preservation tests: rename, add, and delete
|
||
leave the existing named recipient and ID untouched (2 passed).
|
||
- Secured-write approval now treats HTTP 200 with `status: Failed` as CLI failure,
|
||
and rejects malformed or unexpected approval outcomes. Schema/secured focused
|
||
tests: 33 passed, including existing listing behavior and new outcome checks.
|
||
- Fixed a pre-existing blind spot in the actor dispatch gate: its sentinel now
|
||
passes through the configuration transaction before throwing on handler
|
||
dependencies. A negative control detects an unsupported command (2 passed).
|
||
- New CLI tests that invoke Console-writing actions share the Console collection
|
||
to avoid racing tests that redirect process-global output.
|
||
|
||
All implementation packages are present. Final solution verification, canonical
|
||
local deployment, and integration remain in progress.
|
||
|
||
|
||
### Final pre-integration verification
|
||
|
||
- Full solution build: zero warnings and errors.
|
||
- Full solution run (excluding deployed Playwright): 9,551 passed, one failure in
|
||
the UI toast unobserved-exception test. Root cause was unrelated incomplete
|
||
JavaScript success stubs in UI fixtures; no product UI behavior changed.
|
||
- Fixed 15 successful void stubs across 11 fixtures to complete explicitly. Two
|
||
direct regression tests failed before and passed after. Full CentralUI rerun:
|
||
**1,418/1,418 passed**; the original toast assertion remains unchanged.
|
||
- Replacing the initial UI result with the corrected full UI suite gives
|
||
**9,554 passed, zero outstanding failures or skips** across 29 test suites.
|
||
Key suites: CLI **543**, ManagementService **665**, Commons **852**,
|
||
Communication **766**, Integration **118**, Host **598**.
|
||
- Documentation links and `git diff --check` passed. All GAP-01 through GAP-07 and
|
||
PAR-01 through PAR-05 are complete. Canonical deployment and final merge/push
|
||
evidence will be added after integration.
|
||
|
||
Local verification logs: `/tmp/parity-full-build.log`, `/tmp/parity-full-tests.log`,
|
||
`/tmp/parity-ui-red.log`, `/tmp/parity-ui-green.log`, `/tmp/parity-ui-full.log`.
|
||
These logs are local evidence, not committed artifacts.
|
||
|
||
|
||
## Completion and delivery
|
||
|
||
| Final inventory | Count |
|
||
|---|---:|
|
||
| HTTP-eligible management contracts | 149 |
|
||
| Contracts with actor dispatch and observed production CLI HTTP dispatch | 149 |
|
||
| Previously missing CLI operations implemented | 19 of 19 |
|
||
| Unhandled contracts still exposed through HTTP | 0 |
|
||
| Completed gap groups | 7 of 7 |
|
||
| Completed behavioral/contract findings | 5 of 5 |
|
||
|
||
Implementation commit **`2750bd28`** was fast-forward merged from
|
||
`codex/management-cli-parity` into `main`. This completion record accompanies it
|
||
in the final delivery. The original review commit is also included.
|
||
|
||
Final solution build passed with **zero warnings/errors**. The merged-checkout
|
||
CLI suite independently passed **543/543**. Overall verification remains
|
||
**9,554 passing tests** after replacing the initial UI result with its corrected
|
||
full-suite rerun; browser tests were excluded from that count.
|
||
|
||
The canonical `bash docker/deploy.sh` rebuilt and recreated the primary local
|
||
rig with image:
|
||
|
||
`sha256:6e4b3853540723ad0c71376c0100edcdc0a1642aad09e3ecd60de7ca5bd93b30`
|
||
|
||
All eight primary nodes reported readiness 200 and zero restarts. Each of the
|
||
four pairs had one active node (200) and one standby (503). Mount sources and
|
||
destinations matched the pre-deployment snapshot. Initial checks during startup
|
||
returned transient not-ready/no-server responses; the settled checks all passed.
|
||
|
||
Live read-only smoke checks through Traefik passed for `shared-schema list`,
|
||
`secured-write list`, `template list`, `template resolved-members`, `instance list`,
|
||
and `instance native-alarm-source list`. Raw requests for `ReadTagValues` and
|
||
`ResolveRoles` both returned HTTP 400 with `BAD_REQUEST`/unknown-command errors.
|
||
No device writes or live configuration mutations were used for smoke verification.
|
||
|
||
Final local logs: `/tmp/parity-final-build.log`, `/tmp/parity-main-cli.log`,
|
||
`/tmp/parity-deploy.log`, `/tmp/parity-rig-before.json`,
|
||
`/tmp/parity-rig-after.json`, and `/tmp/parity-live-smoke.json`.
|
||
|
||
### CLI documentation follow-up — complete (2026-09-10)
|
||
|
||
- [x] Integrated all new operations into the main CLI command reference and synchronized the component overview and requirements.
|
||
- [x] Documented the five existing external-system method commands that were missing from the README.
|
||
- [x] Corrected stale examples, SMS options, secured-write paging, authorization descriptions, and deployment deadline guidance.
|
||
- [x] Checked the executable help tree: all **159 leaf commands** appear in the reference. Documented example option names and local Markdown links/anchors passed validation. Documentation-only follow-up; runtime verification above remains applicable.
|