Files
ScadaBridge/docs/plans/2026-09-10-management-api-cli-parity-review.md
T

17 KiB
Raw Blame History

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:

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, DeployCommands, InstanceCommands, SiteCommands, ManagementEndpoints.

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, ManagementActor.HandleUpdateNotificationList.

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, notification contracts, ManagementActor.HandleUpdateSmsConfig.

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, ManagementActor, ReadTagValuesCommand, BindingTester.

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, ManagementCommandRegistryTests.

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)

  • Integrated all new operations into the main CLI command reference and synchronized the component overview and requirements.
  • Documented the five existing external-system method commands that were missing from the README.
  • Corrected stale examples, SMS options, secured-write paging, authorization descriptions, and deployment deadline guidance.
  • 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.