363 lines
19 KiB
Markdown
363 lines
19 KiB
Markdown
# Cluster 07 — Contracts/gRPC
|
|
|
|
Audit of `docs/Contracts.md`, `docs/Grpc.md`, and `docs/ClientProtoGeneration.md`
|
|
verified against:
|
|
- `src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_gateway.proto`
|
|
- `src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_worker.proto`
|
|
- `src/ZB.MOM.WW.MxGateway.Contracts/Protos/galaxy_repository.proto`
|
|
- `src/ZB.MOM.WW.MxGateway.Server/Grpc/**`
|
|
- `clients/proto/proto-inputs.json`
|
|
- `src/ZB.MOM.WW.MxGateway.Contracts/ZB.MOM.WW.MxGateway.Contracts.csproj`
|
|
|
|
---
|
|
|
|
DOC / LINES / CLAIM / CLAIM_TYPE / VERDICT / EVIDENCE / CODE_AREA / SEVERITY / PROPOSED_FIX
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 13, 32
|
|
CLAIM: "`MxAccessGatewayService` implements the six `MxAccessGateway` RPCs — `OpenSession`, `CloseSession`, `Invoke`, `StreamEvents`, `AcknowledgeAlarm`, and `StreamAlarms`."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: wrong
|
|
EVIDENCE: mxaccess_gateway.proto:17-38 defines seven RPCs — the six listed plus `QueryActiveAlarms(QueryActiveAlarmsRequest) returns (stream ActiveAlarmSnapshot)`. `MxAccessGatewayService.cs:233` implements `QueryActiveAlarms`. The table at line 13 also says "six" and the table and prose at line 32 both omit `QueryActiveAlarms`.
|
|
CODE_AREA: proto.QueryActiveAlarms
|
|
SEVERITY: high
|
|
PROPOSED_FIX: Change "six" to "seven" in the table and prose. Add `QueryActiveAlarms` to the RPC list at line 32. Add a `### QueryActiveAlarms` handler section describing the server-streaming, session-less snapshot behavior (iterates `alarmService.CurrentAlarms`, respects `alarm_filter_prefix`, completes without emitting transitions).
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 148
|
|
CLAIM: "The mapper exposes static factory methods for every `ProtocolStatusCode` (`Ok`, `InvalidRequest`, `SessionNotFound`, `SessionNotReady`, `WorkerUnavailable`, `Timeout`, `Canceled`, `ProtocolViolation`)."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: wrong
|
|
EVIDENCE: `mxaccess_gateway.proto:1025` defines `PROTOCOL_STATUS_CODE_MXACCESS_FAILURE = 9`. `MxAccessGrpcMapper.cs:76-174` lists eight factory methods — none for `MxAccessFailure`. The claim "every ProtocolStatusCode" is false because `MxAccessFailure` has no corresponding factory method.
|
|
CODE_AREA: proto.ProtocolStatusCode
|
|
SEVERITY: medium
|
|
PROPOSED_FIX: Either add "except `MxAccessFailure`, which is produced only by the worker" to the sentence, or add the missing factory method and update the list. Do not silently elide the gap.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 80, 145
|
|
CLAIM: "Python generated-code output directory is `clients/python/src/mxgateway/generated`."
|
|
CLAIM_TYPE: path
|
|
VERDICT: wrong
|
|
EVIDENCE: `clients/proto/proto-inputs.json:28` declares `"python": "clients/python/src/zb_mom_ww_mxgateway/generated"`. The actual directory on disk is `clients/python/src/zb_mom_ww_mxgateway/generated/` (confirmed by `ls`). The doc path `clients/python/src/mxgateway/generated` does not exist.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: high
|
|
PROPOSED_FIX: Replace both occurrences of `clients/python/src/mxgateway/generated` with `clients/python/src/zb_mom_ww_mxgateway/generated` to match `proto-inputs.json` and the actual filesystem.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 227
|
|
CLAIM: "Under the default policy only the stream is dropped and the session continues to accept commands."
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: wrong
|
|
EVIDENCE: `appsettings.json:53` sets `"BackpressurePolicy": "FailFast"`. `EventOptions.cs:13` confirms `EventBackpressurePolicy.FailFast` as the default. `EventBackpressurePolicy.cs` names the two values `FailFast` and `DisconnectSubscriber`. The non-FailFast (stream-drop-only) behaviour belongs to `DisconnectSubscriber`, not "the default policy". Under the actual default (`FailFast`) the session is faulted.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: medium
|
|
PROPOSED_FIX: Rewrite as: "Under `DisconnectSubscriber` only the stream is dropped … Under `FailFast` (the default configured in `appsettings.json`) the session is faulted …"
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 94, 107
|
|
CLAIM: "Full solution build: `dotnet build src/ZB.MOM.WW.MxGateway.slnx`"
|
|
CLAIM_TYPE: command
|
|
VERDICT: accurate
|
|
EVIDENCE: `src/ZB.MOM.WW.MxGateway.slnx` exists on disk.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 94
|
|
CLAIM: "Run the contracts build to regenerate C# protobuf and gRPC code: `dotnet build src/ZB.MOM.WW.MxGateway.Contracts/ZB.MOM.WW.MxGateway.Contracts.csproj`"
|
|
CLAIM_TYPE: command
|
|
VERDICT: accurate
|
|
EVIDENCE: `ZB.MOM.WW.MxGateway.Contracts.csproj:27-29` includes all three `.proto` files with `GrpcServices="Both"` or `"None"` and `OutputDir="Generated"`. Building the project triggers protoc via Grpc.Tools.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 4-5
|
|
CLAIM: "The contracts project multi-targets `net10.0;net48` and owns the `.proto` files."
|
|
CLAIM_TYPE: config-key
|
|
VERDICT: accurate
|
|
EVIDENCE: `ZB.MOM.WW.MxGateway.Contracts.csproj:4` — `<TargetFrameworks>net10.0;net48</TargetFrameworks>`.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 80-81
|
|
CLAIM: "Generated C# output is written to `src/ZB.MOM.WW.MxGateway.Contracts/Generated/`."
|
|
CLAIM_TYPE: path
|
|
VERDICT: accurate
|
|
EVIDENCE: `ZB.MOM.WW.MxGateway.Contracts.csproj:27` — `OutputDir="Generated"`. Directory `src/ZB.MOM.WW.MxGateway.Contracts/Generated/` contains five generated `.cs` files confirmed by `ls`.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 9-19
|
|
CLAIM: "The public command model includes bulk subscription command kinds for `AddItemBulk`, `AdviseItemBulk`, `RemoveItemBulk`, `UnAdviseItemBulk`, `SubscribeBulk`, and `UnsubscribeBulk`. They return a `BulkSubscribeReply` containing per-item `SubscribeResult` records with `ServerHandle`, `TagAddress`, `ItemHandle`, `WasSuccessful`, and `ErrorMessage`."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: accurate
|
|
EVIDENCE: `mxaccess_gateway.proto:117-122` defines all six payloads. `proto:562-568` defines `SubscribeResult` with fields `server_handle`, `tag_address`, `item_handle`, `was_successful`, `error_message`. `proto:570-572` defines `BulkSubscribeReply`.
|
|
CODE_AREA: proto.SubscribeResult
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 32-45
|
|
CLAIM: "`WriteBulkCommand` / `Write2BulkCommand` / `WriteSecuredBulkCommand` / `WriteSecured2BulkCommand` each carry `server_handle` and a `repeated` list of entries. Each entry mirrors the single-item command shape — `item_handle` + `value` (+ `timestamp_value` on the `*2` variants, + `current_user_id` / `verifier_user_id` on the secured variants). All four replies use `BulkWriteReply` with `repeated BulkWriteResult`. A `BulkWriteResult` has `server_handle`, `item_handle`, `was_successful`, `optional int32 hresult`, `repeated MxStatusProxy statuses`, and `error_message`."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: accurate
|
|
EVIDENCE: `mxaccess_gateway.proto:384-441` defines all four commands with matching fields. `proto:581-588` defines `BulkWriteResult` with exactly those six fields. `proto:590-592` defines `BulkWriteReply`.
|
|
CODE_AREA: proto.BulkWriteResult
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 46-61
|
|
CLAIM: "`ReadBulkCommand` carries `server_handle`, `repeated string tag_addresses`, and `uint32 timeout_ms`. The reply is `BulkReadReply` carrying `repeated BulkReadResult`. A `BulkReadResult` has `server_handle`, `tag_address`, `item_handle`, `was_successful`, `was_cached`, `value`, `quality`, `source_timestamp`, `repeated MxStatusProxy statuses`, and `error_message`. `BulkReadResult` has no `hresult` field."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: accurate
|
|
EVIDENCE: `mxaccess_gateway.proto:456-460` defines `ReadBulkCommand` with those three fields. `proto:612-623` defines `BulkReadResult` with exactly those ten fields, no `hresult`. `proto:625-627` defines `BulkReadReply`.
|
|
CODE_AREA: proto.BulkReadResult
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 68-71
|
|
CLAIM: "`mxaccess_worker.proto` defines the named-pipe worker IPC envelope and control messages. It imports `mxaccess_gateway.proto` so the worker and gateway use the same command, reply, event, value, and status shapes."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: accurate
|
|
EVIDENCE: `mxaccess_worker.proto:9` — `import "mxaccess_gateway.proto";`. The `WorkerCommand`, `WorkerCommandReply`, `WorkerEvent` messages wrap `mxaccess_gateway.v1` types directly.
|
|
CODE_AREA: proto.WorkerEnvelope
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md
|
|
LINES: 73-78
|
|
CLAIM: "`galaxy_repository.proto` defines the `GalaxyRepository` service. The service is metadata-only and does not share types with `mxaccess_gateway.proto`."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: accurate
|
|
EVIDENCE: `galaxy_repository.proto:7-8` imports only `google/protobuf/timestamp.proto` and `google/protobuf/wrappers.proto` — no import of `mxaccess_gateway.proto`. The comment at `galaxy_repository.proto:130` states the type enumeration is distinct from `MxDataType`.
|
|
CODE_AREA: proto.GalaxyRepository
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 9-16
|
|
CLAIM: "Four collaborators: `MxAccessGatewayService` (scoped/gRPC), `MxAccessGrpcRequestValidator` (singleton), `MxAccessGrpcMapper` (singleton), `IEventStreamService`/`EventStreamService` (singleton)."
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: accurate
|
|
EVIDENCE: `GatewayApplication.cs:88-90` registers mapper, validator, and event stream service as singletons. `MxAccessGatewayService` is not explicitly registered (gRPC services resolved per-request by ASP.NET Core are transient/scoped — "scoped (gRPC)" is accurate per ASP.NET Core DI conventions). `GatewayApplication.cs:195` maps it as a gRPC endpoint.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 20-26
|
|
CLAIM: "Registration: `builder.Services.AddSingleton<MxAccessGrpcMapper>(); builder.Services.AddSingleton<MxAccessGrpcRequestValidator>(); builder.Services.AddSingleton<IEventStreamService, EventStreamService>();`"
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: accurate
|
|
EVIDENCE: `GatewayApplication.cs:88-90` matches exactly.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 237-243
|
|
CLAIM: "Authorization interceptor registration: `services.AddSingleton<GatewayGrpcAuthorizationInterceptor>(); services.AddGrpc(options => options.Interceptors.Add<GatewayGrpcAuthorizationInterceptor>());`"
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: accurate
|
|
EVIDENCE: `GrpcAuthorizationServiceCollectionExtensions.cs:21,31` contains both lines verbatim.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 100-108
|
|
CLAIM: "Validation table — `OpenSession`: `command_timeout` when set must be `> 0`; `CloseSession`: `session_id` non-empty; `StreamEvents`: `session_id` non-empty; `Invoke`: session_id non-empty, command present, kind not Unspecified, payload oneof matches kind; `AcknowledgeAlarm`: `alarm_full_reference` non-empty, validated inline not by `MxAccessGrpcRequestValidator`; `StreamAlarms`: no required fields."
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: accurate
|
|
EVIDENCE: `MxAccessGrpcRequestValidator.cs:10-53` confirms all four validator methods. `MxAccessGatewayService.cs:181-183` confirms the inline alarm reference check. `StreamAlarms` handler at line 204 has no field validation.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 141-147
|
|
CLAIM: "When the worker reply or event payload is missing, the mapper returns a synthetic public message with `ProtocolStatusCode.ProtocolViolation` (for replies) or a sentinel `MxEvent` with `MxEventFamily.Unspecified` (for events)."
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: accurate
|
|
EVIDENCE: `MxAccessGrpcMapper.cs:46-54` returns `ProtocolViolation(...)` when `reply.Reply` is null. `MxAccessGrpcMapper.cs:65-69` returns sentinel `MxEvent { Family = MxEventFamily.Unspecified }` when event is null.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 159-174
|
|
CLAIM: "Exception mapping: `OperationCanceledException` → `Cancelled`; `SessionManagerException` → mapped by `ErrorCode`; `WorkerClientException` → mapped by `ErrorCode`. `WorkerClientException`: `CommandTimeout` → `DeadlineExceeded`, `GatewayShutdown` → `Cancelled`, `InvalidState` → `FailedPrecondition`, `ProtocolViolation` → `Internal`, others → `Unavailable`."
|
|
CLAIM_TYPE: behavior-rule
|
|
VERDICT: accurate
|
|
EVIDENCE: `MxAccessGatewayService.cs:902-950` matches exactly. `WorkerClientErrorCode.cs:5-12` confirms the four enum values.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Grpc.md
|
|
LINES: 184-196
|
|
CLAIM: "The channel is bounded by `Events:QueueCapacity` and configured for a single reader and writer with `FullMode = BoundedChannelFullMode.Wait` and `AllowSynchronousContinuations = false`."
|
|
CLAIM_TYPE: config-key
|
|
VERDICT: accurate
|
|
EVIDENCE: `EventStreamService.cs:44-51` matches the code snippet in the doc verbatim.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 39-45
|
|
CLAIM: "`GatewayContractInfo.GatewayProtocolVersion` is the public gateway protocol version. `OpenSessionReply.gateway_protocol_version` returns the same value."
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: accurate
|
|
EVIDENCE: `GatewayContractInfo.cs:12` — `public const uint GatewayProtocolVersion = 3;`. `mxaccess_gateway.proto:71` — `uint32 gateway_protocol_version = 8;`. `MxAccessGatewayService.cs:49` copies `GatewayContractInfo.GatewayProtocolVersion` into the reply field.
|
|
CODE_AREA: proto.OpenSessionReply
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 55-61
|
|
CLAIM: "The script writes `clients/proto/descriptors/mxaccessgw-client-v1.protoset`."
|
|
CLAIM_TYPE: path
|
|
VERDICT: accurate
|
|
EVIDENCE: `clients/proto/descriptors/mxaccessgw-client-v1.protoset` exists on disk. `proto-inputs.json:21` references the same path.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 74-81
|
|
CLAIM: "Generated-code directories table: .NET → `clients/dotnet/generated`, Go → `clients/go/internal/generated`, Rust → `clients/rust/src/generated`, Python → `clients/python/src/mxgateway/generated`, Java → `clients/java/src/main/generated`."
|
|
CLAIM_TYPE: path
|
|
VERDICT: wrong
|
|
EVIDENCE: `clients/proto/proto-inputs.json:26-30` lists `"python": "clients/python/src/zb_mom_ww_mxgateway/generated"`. The actual directory is `clients/python/src/zb_mom_ww_mxgateway/generated/` (confirmed by filesystem). The table row for Python says `clients/python/src/mxgateway/generated` which does not exist. All other rows match `proto-inputs.json` and the filesystem.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: high
|
|
PROPOSED_FIX: Change the Python row from `clients/python/src/mxgateway/generated` to `clients/python/src/zb_mom_ww_mxgateway/generated` in the table and also fix line 145 which contains the same wrong path.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 89-101 (generation commands table)
|
|
CLAIM: ".NET generation: `dotnet build src/ZB.MOM.WW.MxGateway.Contracts/ZB.MOM.WW.MxGateway.Contracts.csproj`; Go: `Push-Location clients/go; ./generate-proto.ps1; Pop-Location`; Rust: `Push-Location clients/rust; cargo check --workspace; Pop-Location`; Python: `Push-Location clients/python; ./generate-proto.ps1; Pop-Location`; Java: `Push-Location clients/java; gradle :mxgateway-client:generateProto; Pop-Location`."
|
|
CLAIM_TYPE: command
|
|
VERDICT: accurate
|
|
EVIDENCE: Scripts `clients/go/generate-proto.ps1` and `clients/python/generate-proto.ps1` exist. `generate-proto.ps1` for Go uses `$modulePath = 'gitea.dohertylan.com/dohertj2/mxaccessgw/clients/go/internal/generated'` matching the stated package. Contracts csproj exists. All scripts confirmed present.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 119-125
|
|
CLAIM: "The Go scaffold maps both proto files into the internal Go package `gitea.dohertylan.com/dohertj2/mxaccessgw/clients/go/internal/generated`."
|
|
CLAIM_TYPE: path
|
|
VERDICT: accurate
|
|
EVIDENCE: `clients/go/generate-proto.ps1:7` — `$modulePath = 'gitea.dohertylan.com/dohertj2/mxaccessgw/clients/go/internal/generated'`.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/ClientProtoGeneration.md
|
|
LINES: 170-176
|
|
CLAIM: "Golden fixtures: `open-session-reply.ok.json`, `register-command-request.json`, `on-data-change-event.json`."
|
|
CLAIM_TYPE: path
|
|
VERDICT: accurate
|
|
EVIDENCE: All three files exist at `clients/proto/fixtures/golden/`.
|
|
CODE_AREA: proto.gen
|
|
SEVERITY: low
|
|
PROPOSED_FIX: None.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md / docs/ClientProtoGeneration.md
|
|
LINES: (gap — not documented)
|
|
CLAIM: gap — `QueryActiveAlarms` RPC in `mxaccess_gateway.proto` service definition (line 37), `QueryActiveAlarmsRequest` message (line 44), and `ActiveAlarmSnapshot` message (line 783) are not mentioned in `Contracts.md` or `ClientProtoGeneration.md`.
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: gap
|
|
EVIDENCE: `mxaccess_gateway.proto:37` — `rpc QueryActiveAlarms(QueryActiveAlarmsRequest) returns (stream ActiveAlarmSnapshot);`. `Contracts.md` describes every other public RPC but never mentions `QueryActiveAlarms`.
|
|
CODE_AREA: proto.QueryActiveAlarms
|
|
SEVERITY: medium
|
|
PROPOSED_FIX: Add a paragraph to `Contracts.md` describing `QueryActiveAlarms` — session-less, server-streaming, returns point-in-time snapshot of active alarms from the gateway's always-on alarm monitor cache, optionally filtered by `alarm_filter_prefix`. Cross-reference the `StreamAlarms` section.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md / docs/ClientProtoGeneration.md
|
|
LINES: (gap — not documented)
|
|
CLAIM: gap — `AlarmFeedMessage` oneof message and the `StreamAlarms` protocol (snapshot → `snapshot_complete` → transitions) are described in `Grpc.md` but not in `Contracts.md` which should be the shape-level reference.
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: gap
|
|
EVIDENCE: `mxaccess_gateway.proto:860-870` defines `AlarmFeedMessage { oneof payload { ActiveAlarmSnapshot active_alarm = 1; bool snapshot_complete = 2; OnAlarmTransitionEvent transition = 3; } }`. `Contracts.md` does not describe this message or its stream protocol.
|
|
CODE_AREA: proto.AlarmFeedMessage
|
|
SEVERITY: low
|
|
PROPOSED_FIX: Add a brief entry in `Contracts.md` describing `AlarmFeedMessage` and the three-phase stream sequence for `StreamAlarms`.
|
|
|
|
---
|
|
|
|
DOC: docs/Contracts.md / docs/Grpc.md
|
|
LINES: (gap — not documented)
|
|
CLAIM: gap — `AcknowledgeAlarmRequest` has a reserved field 1 (`session_id`) and the acknowledgement is session-less. `AcknowledgeAlarmReply` also has a reserved field 1 and an intentionally-unset `status` field (field 5). This wire-compatibility detail is not captured in `Contracts.md`.
|
|
CLAIM_TYPE: rpc/proto
|
|
VERDICT: gap
|
|
EVIDENCE: `mxaccess_gateway.proto:812-847` — `AcknowledgeAlarmRequest` has `reserved 1; reserved "session_id";`. `AcknowledgeAlarmReply` likewise has `reserved 1; reserved "session_id";` and inline comment that `status` (field 5) is intentionally unset.
|
|
CODE_AREA: proto.AcknowledgeAlarm
|
|
SEVERITY: low
|
|
PROPOSED_FIX: Add a note in `Contracts.md` about the reserved `session_id` fields and the intentionally-empty `status` field so integrators using older generated code do not misinterpret wire defaults.
|