@derec-alliance/nodejs 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,194 @@
1
+ /*
2
+ * Copyright (c) DeRec Alliance and its Contributors.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ syntax = "proto3";
7
+
8
+ package org.derecalliance.derec.protobuf;
9
+
10
+ // Result represents the outcome of processing a DeRec protocol request.
11
+ //
12
+ // # Purpose
13
+ //
14
+ // This message is included in response messages to communicate:
15
+ //
16
+ // - whether a request was successfully processed
17
+ // - the type of failure (if any)
18
+ // - optional human-readable context for debugging or user display
19
+ //
20
+ // # Semantics
21
+ //
22
+ // A Result consists of:
23
+ //
24
+ // - a machine-readable `status` code
25
+ // - an optional `memo` providing additional context
26
+ //
27
+ // The `status` field MUST be used by implementations to determine
28
+ // protocol behavior. The `memo` field is informational only.
29
+ //
30
+ // # Usage
31
+ //
32
+ // - Every response message that can fail SHOULD include a Result
33
+ // - Senders MUST inspect the `status` field to determine next steps
34
+ // - The `memo` field MAY be displayed to users or logged for diagnostics
35
+ //
36
+ // # Security Considerations
37
+ //
38
+ // - The `memo` field SHOULD NOT include sensitive internal details
39
+ // - Only high-level or user-safe information should be exposed
40
+ //
41
+ // # Idempotency
42
+ //
43
+ // The Result reflects the outcome of a specific request. Repeated identical
44
+ // requests SHOULD produce consistent Result values unless system state changes.
45
+ message DeRecResult {
46
+ // Status code indicating the outcome of the request.
47
+ StatusEnum status = 1;
48
+
49
+ // Optional human-readable description providing additional details.
50
+ //
51
+ // This field is intended for debugging, logging, or user display.
52
+ // It MUST NOT be relied upon for programmatic decision-making.
53
+ string memo = 2;
54
+ }
55
+
56
+ // StatusEnum defines the set of possible outcomes for processing
57
+ // DeRec protocol requests.
58
+ //
59
+ // # Semantics
60
+ //
61
+ // These values are used across all response messages to provide a consistent
62
+ // interpretation of success and failure conditions.
63
+ //
64
+ // Implementations MUST handle all known values and SHOULD safely ignore
65
+ // unknown values for forward compatibility.
66
+ enum StatusEnum {
67
+
68
+ // The request was successfully handled.
69
+ //
70
+ // No further action is required by the sender.
71
+ OK = 0;
72
+
73
+ // The request was partially fulfilled.
74
+ //
75
+ // The `memo` field SHOULD provide additional context explaining which
76
+ // parts succeeded and which did not.
77
+ PARTIAL = 1;
78
+
79
+ // The request failed for a generic or unspecified reason.
80
+ //
81
+ // The `memo` field MAY provide additional details.
82
+ FAIL = 2;
83
+
84
+ // The request failed because it would exceed the allowed storage limit
85
+ // for this sharer and secret ID.
86
+ //
87
+ // This typically applies to share storage operations.
88
+ SIZE_LIMIT_EXCEEDED = 3;
89
+
90
+ // The request was ignored because it exceeded the allowed frequency.
91
+ //
92
+ // This may be used for rate limiting to prevent abuse or excessive load.
93
+ TOO_FREQUENT = 4;
94
+
95
+ // The specified secret ID is not recognized by the Helper.
96
+ //
97
+ // This may occur during recovery or share retrieval.
98
+ UNKNOWN_SECRET_ID = 5;
99
+
100
+ // The specified share version does not exist for the given secret ID.
101
+ //
102
+ // This may occur if the version was never stored or has been deleted.
103
+ UNKNOWN_SHARE_VERSION = 6;
104
+
105
+ // The message could not be decrypted successfully.
106
+ //
107
+ // This indicates a failure in the cryptographic layer, such as:
108
+ //
109
+ // - incorrect key material
110
+ // - corrupted ciphertext
111
+ DECRYPTION_FAILED = 7;
112
+
113
+ // The message signature or authentication could not be verified.
114
+ //
115
+ // This indicates that the message integrity or authenticity check failed.
116
+ VERIFICATION_FAILED = 8;
117
+
118
+ // The message format is invalid.
119
+ //
120
+ // This includes errors such as:
121
+ //
122
+ // - protobuf parsing failures
123
+ // - missing required fields
124
+ // - structurally invalid messages
125
+ FORMAT_ERROR = 9;
126
+
127
+ // The request was rejected by the counter-party
128
+ //
129
+ // This might be used to indicate the user or system that received the
130
+ // requested rejected it.
131
+ REJECTED = 10;
132
+
133
+ // The pair handshake failed because the two parties' advertised
134
+ // `ParameterRange` values do not overlap on at least one field
135
+ // (e.g. local `minShareSize` exceeds peer `maxShareSize`).
136
+ //
137
+ // Sent on a `PairResponseMessage`; the `memo` field SHOULD describe
138
+ // the offending field and the two `(min, max)` pairs so the
139
+ // initiator can surface a useful diagnostic.
140
+ INCOMPATIBLE_PARAMETER_RANGE = 11;
141
+
142
+ // The announced transport protocol is one the recipient cannot serve.
143
+ //
144
+ // Returned only for a transport change on an **already-established**
145
+ // channel — an `UpdateChannelInfo` announcing a switch the recipient
146
+ // cannot follow. The recipient still holds the peer's previous working
147
+ // endpoint, which is what makes this refusal deliverable at all.
148
+ //
149
+ // It is deliberately **not** used during pairing. Delivery is push-only,
150
+ // so a party that cannot reach a peer also cannot deliver a rejection to
151
+ // it; pairing incompatibility surfaces locally to the application
152
+ // instead.
153
+ UNSUPPORTED_TRANSPORT_PROTOCOL = 12;
154
+
155
+ // A share already exists for this (secretId, version) with different
156
+ // content, so the write was refused.
157
+ //
158
+ // Exactly one writer owns a version. A recipient stores the first write
159
+ // it sees at a version; a later write carrying different bytes is
160
+ // rejected with this status rather than overwriting or coexisting. A
161
+ // byte-identical re-send is an idempotent retry and returns `OK`.
162
+ //
163
+ // Because a single writer always derives `version` as
164
+ // `latest_version + 1`, it can never rewrite a version with different
165
+ // content. Receiving this status therefore means a *second* writer
166
+ // published concurrently — typically the same user acting on two
167
+ // devices at once. Resolution is the application's responsibility: the
168
+ // round has failed and should be republished at a new version.
169
+ VERSION_CONFLICT = 13;
170
+
171
+ // A replica pairing named a `replicaId` that is already in use by another
172
+ // member of the group — including the recipient itself.
173
+ //
174
+ // Every member of a group must be uniquely identified: the roster is keyed
175
+ // by `replicaId`, and messages between members are attributed by it. Two
176
+ // members sharing an id would overwrite each other's roster row and make
177
+ // every acknowledgement ambiguous.
178
+ //
179
+ // `replicaId` is assigned by the application, so a collision is a
180
+ // configuration fault — most often the same identity reused on two devices,
181
+ // such as a cloned device image. Resolution is the application's: assign a
182
+ // distinct id and pair again. The protocol cannot pick one, because it
183
+ // cannot know which device is meant to keep the original.
184
+ //
185
+ // Reported before fingerprint verification: there is no point asking a user
186
+ // to confirm a pairing that cannot be completed.
187
+ REPLICA_ID_CONFLICT = 14;
188
+
189
+ // The Helper is requesting that the Owner terminate the relationship.
190
+ //
191
+ // The Owner SHOULD respond by sending an UnpairRequestMessage and
192
+ // ceasing further communication on the channel.
193
+ REQUEST_TO_CLOSE = 99;
194
+ }
@@ -0,0 +1,209 @@
1
+ /*
2
+ * Copyright (c) DeRec Alliance and its Contributors.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ syntax = "proto3";
7
+
8
+ import "google/protobuf/timestamp.proto";
9
+ import "result.proto";
10
+ import "transportprotocol.proto";
11
+
12
+ package org.derecalliance.derec.protobuf;
13
+
14
+ // GetSecretIdsVersionsRequestMessage requests the list of all secrets and
15
+ // corresponding share versions that a Helper stores for a given Owner.
16
+ //
17
+ // # Context
18
+ //
19
+ // This message is used during the recovery flow, after the Owner has
20
+ // re-paired with a Helper (typically in recovery mode).
21
+ //
22
+ // Since the recovering Owner does not know which secrets or versions
23
+ // the Helper holds, this message allows discovery of:
24
+ //
25
+ // - all secretIds associated with the Owner
26
+ // - all share versions stored for each secret
27
+ //
28
+ // # Semantics
29
+ //
30
+ // The Helper responds with a GetSecretIdsVersionsResponseMessage containing:
31
+ //
32
+ // - one entry per secretId
33
+ // - the list of versions stored for each secret
34
+ //
35
+ // # Authorization Rules
36
+ //
37
+ // The Helper MUST only fully process this request if it is received through
38
+ // a communication channel that was established in recovery mode and has been
39
+ // associated (via authentication) with the same Owner as previously stored
40
+ // secrets.
41
+ //
42
+ // If this condition is not met, the Helper MAY:
43
+ //
44
+ // - return only partial information (e.g., for the current channel), or
45
+ // - reject the request entirely
46
+ //
47
+ // # Authentication
48
+ //
49
+ // The Helper MUST authenticate the requester at the application level before
50
+ // disclosing any information about stored secrets. Authentication is outside
51
+ // the scope of the protocol and may include:
52
+ //
53
+ // - in-person verification
54
+ // - KYC processes
55
+ // - biometrics or credentials
56
+ //
57
+ // # Idempotency
58
+ //
59
+ // This request is idempotent. Repeated requests SHOULD return the same
60
+ // information unless the underlying storage changes.
61
+ message GetSecretIdsVersionsRequestMessage {
62
+ // Timestamp indicating when this message was created.
63
+ //
64
+ // This value is expressed in UTC and can be used for:
65
+ //
66
+ // - observability and logging
67
+ // - replay detection (in combination with sequence numbers)
68
+ // - timeout handling
69
+ google.protobuf.Timestamp timestamp = 1;
70
+
71
+ // Ephemeral transport endpoint at which the requester wants to receive
72
+ // the response to *this exchange*, overriding the channel's stored peer
73
+ // endpoint for this round-trip only.
74
+ //
75
+ // See `StoreShareRequestMessage.replyTo` for full semantics.
76
+ //
77
+ // Superseded by `replyToTransports`, which carries every endpoint rather
78
+ // than one. Kept, and still populated with the list's first entry, so
79
+ // implementations predating that field still receive a reply.
80
+ // **Scheduled for removal in v0.0.5.** Reading this field directly is now
81
+ // incorrect — resolve it against `replyToTransports`.
82
+ optional TransportProtocol replyTo = 2 [deprecated = true];
83
+
84
+ // Every ephemeral endpoint the requester wants this exchange's response
85
+ // delivered to, in its own preference order.
86
+ //
87
+ // See `StoreShareRequestMessage.replyToTransports` for full semantics,
88
+ // including why this is a new tag rather than a widened `replyTo`.
89
+ repeated TransportProtocol replyToTransports = 4;
90
+
91
+ // Identity of the replica-group member this message concerns.
92
+ //
93
+ // Present **only** on the replica path, where a member drives catch-up
94
+ // against another member. Absent on the owner ↔ helper path, which is
95
+ // unchanged.
96
+ //
97
+ // Every member of a group is addressed on one shared `channel_id`, so the
98
+ // channel cannot name the peer — this field does. Its presence is also what
99
+ // tells the receiver which path a message belongs to.
100
+ optional uint64 replicaId = 3;
101
+ }
102
+
103
+
104
+ // GetSecretIdsVersionsResponseMessage returns the list of all secrets and
105
+ // their corresponding share versions stored by the Helper for the Owner.
106
+ //
107
+ // # Semantics
108
+ //
109
+ // Each entry in `secretList` represents:
110
+ //
111
+ // - a `secretId` previously shared by the Owner
112
+ // - the list of share versions currently stored for that secret
113
+ //
114
+ // This allows the recovering Owner to:
115
+ //
116
+ // - discover which secrets exist
117
+ // - determine which versions to request via GetShareRequestMessage
118
+ //
119
+ // # Authorization and Privacy
120
+ //
121
+ // The Helper MUST ensure that:
122
+ //
123
+ // - the requester is authenticated as the same Owner
124
+ // - the request originates from a recovery-mode channel
125
+ //
126
+ // Only under these conditions may the Helper return the full list of secrets.
127
+ //
128
+ // Otherwise, the Helper MUST:
129
+ //
130
+ // - return partial data (e.g., only for the current secretId), or
131
+ // - return a failure result
132
+ //
133
+ // # Security Considerations
134
+ //
135
+ // - This message reveals metadata about stored secrets
136
+ // - It MUST only be sent over an authenticated and encrypted channel
137
+ // - Unauthorized disclosure could leak information about user activity
138
+ //
139
+ // # Idempotency
140
+ //
141
+ // For a given Helper state, repeated responses SHOULD return the same data.
142
+ message GetSecretIdsVersionsResponseMessage {
143
+
144
+ // Result of processing the request.
145
+ //
146
+ // Indicates whether the request was successfully processed or rejected.
147
+ DeRecResult result = 1;
148
+
149
+ // List of secrets and their stored versions.
150
+ //
151
+ // Each entry corresponds to one secretId and the versions available
152
+ // for that secret.
153
+ repeated VersionList secretList = 2;
154
+
155
+ // Timestamp indicating when this message was created.
156
+ //
157
+ // This value is expressed in UTC and can be used for:
158
+ //
159
+ // - observability and logging
160
+ // - replay detection (in combination with sequence numbers)
161
+ // - timeout handling
162
+ google.protobuf.Timestamp timestamp = 3;
163
+
164
+ // Identity of the replica-group member this message concerns.
165
+ //
166
+ // Present **only** on the replica path, where a member drives catch-up
167
+ // against another member. Absent on the owner ↔ helper path, which is
168
+ // unchanged.
169
+ //
170
+ // Every member of a group is addressed on one shared `channel_id`, so the
171
+ // channel cannot name the peer — this field does. Its presence is also what
172
+ // tells the receiver which path a message belongs to.
173
+ optional uint64 replicaId = 4;
174
+
175
+ // VersionList groups the share versions stored for a single secretId.
176
+ //
177
+ // # Semantics
178
+ //
179
+ // - `secretId` uniquely identifies a secret
180
+ // - `versions` lists all share versions currently stored for that secret,
181
+ // each paired with a human-readable description
182
+ //
183
+ // The order of versions is not significant unless defined by the
184
+ // implementation.
185
+ message VersionList {
186
+ // Identifier of the secret.
187
+ uint64 secretId = 1;
188
+
189
+ // List of share versions stored for this secret.
190
+ //
191
+ // Each entry carries the numeric version identifier together with the
192
+ // human-readable description that was supplied by the Owner when the
193
+ // share was stored. Descriptions help the recovering Owner identify
194
+ // which secret corresponds to which identifier without relying on
195
+ // raw bytes alone.
196
+ repeated VersionEntry versions = 2;
197
+
198
+ // One stored version of a secret, paired with its human-readable label.
199
+ message VersionEntry {
200
+ // Numeric version identifier.
201
+ uint32 version = 1;
202
+
203
+ // Human-readable description supplied by the Owner at share-storage time.
204
+ //
205
+ // May be empty if no description was provided.
206
+ string versionDescription = 2;
207
+ }
208
+ }
209
+ }
@@ -0,0 +1,274 @@
1
+ /*
2
+ * Copyright (c) DeRec Alliance and its Contributors.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ syntax = "proto3";
7
+
8
+ import "google/protobuf/timestamp.proto";
9
+ import "result.proto";
10
+ import "transportprotocol.proto";
11
+
12
+ package org.derecalliance.derec.protobuf;
13
+
14
+ // StoreShareRequestMessage instructs a Helper to store a share for a given
15
+ // secret and manage the set of retained share versions.
16
+ //
17
+ // # Context
18
+ //
19
+ // This message is used in the sharing flow when:
20
+ //
21
+ // - a new secret is created
22
+ // - an existing secret is updated
23
+ // - the helper set or recovery threshold changes
24
+ //
25
+ // The Owner sends this message to each Helper to:
26
+ //
27
+ // - store (or replace) a specific share version
28
+ // - update the set of versions that must be retained (keepList)
29
+ //
30
+ // # Semantics
31
+ //
32
+ // This message may carry two independent instructions:
33
+ //
34
+ // 1. Share storage/update:
35
+ // - If `share` is present, the Helper MUST store this share under the
36
+ // specified `version`
37
+ // - If the version already exists, the Helper MUST replace it
38
+ //
39
+ // 2. Retention policy update:
40
+ // - If `keepList` is present, it defines the complete set of versions
41
+ // that MUST be retained
42
+ // - Any stored version not in `keepList` SHOULD be deleted
43
+ //
44
+ // If `keepList` is absent:
45
+ //
46
+ // - The Helper MUST preserve the existing keepList
47
+ // - The Helper MUST add the new `version` to the retained set
48
+ //
49
+ // # Consistency Requirements
50
+ //
51
+ // The Owner MUST ensure that for a given (secretId, version):
52
+ //
53
+ // - all Helpers receive identical share contents
54
+ //
55
+ // It is an error for different shares to be associated with the same
56
+ // version and secretId.
57
+ //
58
+ // # Replay Protection
59
+ //
60
+ // To prevent replay attacks:
61
+ //
62
+ // - If `version` is less than the latest stored version,
63
+ // the Helper MUST ignore the `keepList` field
64
+ //
65
+ // This ensures that stale messages cannot cause deletion of newer shares.
66
+ //
67
+ // # Share Opacity
68
+ //
69
+ // The Helper MUST treat the `share` field as opaque data. It is not required
70
+ // to understand or validate the share contents.
71
+ //
72
+ // # Idempotency
73
+ //
74
+ // This message is idempotent:
75
+ //
76
+ // - Re-sending the same (version, share) pair SHOULD result in the same state
77
+ // - Re-applying the same keepList SHOULD not change state after the first time
78
+ message StoreShareRequestMessage {
79
+
80
+ // Share bytes to be stored by the Helper.
81
+ //
82
+ // This is an opaque byte array produced by the share distribution
83
+ // algorithm. The Helper MUST store it without interpretation.
84
+ bytes share = 1;
85
+
86
+ // Identifier of the algorithm used to produce the share.
87
+ //
88
+ // This allows the Owner and Helper to coordinate on how the share
89
+ // should be interpreted during recovery.
90
+ //
91
+ // Algorithm 0 defines the share as a serialized `CommittedDeRecShare`
92
+ // protobuf message (see DeRec cryptography repository).
93
+ //
94
+ // Implementations SHOULD support algorithm 0 for interoperability.
95
+ int32 shareAlgorithm = 2;
96
+
97
+
98
+ // Identifier of the secret to which this share belongs.
99
+ //
100
+ // Used by the Helper to associate the share with the correct secret in the
101
+ // share store under the composite key (channel_id, secret_id, version).
102
+ uint64 secretId = 3;
103
+
104
+ // Version number of the share.
105
+ //
106
+ // Each resharing event increments this value.
107
+ uint32 version = 4;
108
+
109
+ // List of share versions that MUST be retained by the Helper.
110
+ //
111
+ // Any stored version not included in this list SHOULD be deleted.
112
+ //
113
+ // If absent, the Helper MUST:
114
+ //
115
+ // - retain the existing keepList
116
+ // - add the current `version` to the retained set
117
+ //
118
+ // This field MUST be ignored if `version` is older than the latest
119
+ // version already stored, to prevent replay attacks.
120
+ repeated uint32 keepList = 5;
121
+
122
+ // Optional human-readable description of this share version.
123
+ //
124
+ // This field is visible to the Helper and is not intended to carry
125
+ // sensitive information. It may be used for debugging, labeling, or
126
+ // user-facing display.
127
+ string versionDescription = 6;
128
+
129
+ // Timestamp indicating when this message was created.
130
+ //
131
+ // Used for observability, replay detection, and timeout handling.
132
+ google.protobuf.Timestamp timestamp = 7;
133
+
134
+ // Ephemeral transport endpoints at which the requester wants to receive
135
+ // the response to *this exchange*, in its own preference order,
136
+ // overriding the channel's stored peer endpoints for this round-trip
137
+ // only.
138
+ //
139
+ // # When to use
140
+ //
141
+ // Set when the requester's outbound endpoint does not match the endpoint
142
+ // the responder has on file for the channel — for example a replica
143
+ // talking to a helper that was paired with a sibling replica. The
144
+ // responder routes the response here but does NOT persist these
145
+ // endpoints; use `UpdateChannelInfoRequestMessage` for permanent changes.
146
+ //
147
+ // # Semantics
148
+ //
149
+ // - Absent (the default): the responder routes to the endpoints stored on
150
+ // its `Channel` record for this `channelId`.
151
+ // - Present: the responder routes this exchange's response here, and
152
+ // leaves the stored endpoints unchanged.
153
+ //
154
+ // Superseded by `replyToTransports`, which carries every endpoint rather
155
+ // than one. Kept, and still populated with the list's first entry, so
156
+ // implementations predating that field still receive a reply.
157
+ // **Scheduled for removal in v0.0.5.**
158
+ //
159
+ // **Reading this field directly is now incorrect** for the same reason it
160
+ // is on `transportProtocol`: it is one entry of a list and may be absent.
161
+ // Resolve it against `replyToTransports` instead.
162
+ optional TransportProtocol replyTo = 8 [deprecated = true];
163
+
164
+ // Every ephemeral endpoint the requester wants this exchange's response
165
+ // delivered to, in its own preference order.
166
+ //
167
+ // # Semantics
168
+ //
169
+ // - Empty, and `replyTo` absent: the responder routes to the endpoints
170
+ // stored on its `Channel` record for this `channelId`.
171
+ // - Empty, `replyTo` present: that one endpoint, which is how every
172
+ // implementation predating this field asks.
173
+ // - Non-empty: the responder routes the response to any one of these, in
174
+ // the order given, and leaves the stored endpoints unchanged. Delivery
175
+ // to any one is success.
176
+ //
177
+ // # Why this is a new field rather than a wider `replyTo`
178
+ //
179
+ // `replyTo` was singular through 0.0.2. Re-tagging it `repeated` would
180
+ // have been wire-compatible in the read direction only: protobuf merges a
181
+ // repeated submessage into a singular reader field-by-field, so a 0.0.2
182
+ // peer decoding a multi-entry list sees the **last** entry, while the
183
+ // first entry is what every other compatibility rule in this release
184
+ // designates as the legacy-readable one. One list cannot be ordered to
185
+ // satisfy both. A new tag lets the singular field keep meaning exactly
186
+ // what it did — the same shape `supportedTransports` (contact.proto tag 9)
187
+ // uses beside `transportProtocol` (tag 7).
188
+ repeated TransportProtocol replyToTransports = 10;
189
+
190
+ // Identity of the replica that authored this update.
191
+ //
192
+ // # Audience
193
+ //
194
+ // This field is for **replicas only**. Helpers know nothing about
195
+ // replicas and never receive it:
196
+ //
197
+ // - helper-bound (`SHARE_ALGORITHM_VSS`) — MUST be absent.
198
+ // - replica-bound (`SHARE_ALGORITHM_REPLICA_SECRET`) — MUST be present.
199
+ //
200
+ // The invariant is `replicaId.is_some() == (shareAlgorithm ==
201
+ // SHARE_ALGORITHM_REPLICA_SECRET)`, asserted on send and on receive; a
202
+ // violation is a protocol error, not a tolerated variation.
203
+ //
204
+ // # Why the receiver needs it
205
+ //
206
+ // Every member of a replica group shares one `channelId`, so the
207
+ // channel identifies the *group*, not the sender. The channel's
208
+ // counterparty says who established it, which after admission by a
209
+ // third member is not who wrote this message. Author attribution
210
+ // therefore comes from this field and never from the channel record.
211
+ //
212
+ // Applications use it to resolve which member published an update, and
213
+ // to route the response back to that member's endpoint.
214
+ //
215
+ // # Out of scope for the protocol
216
+ //
217
+ // The protocol does not authenticate the claim; anyone holding the
218
+ // group key may write any `replicaId`. It is an identifier, not an
219
+ // authenticator.
220
+ optional uint64 replicaId = 9;
221
+ }
222
+
223
+ // StoreShareResponseMessage is the response to a StoreShareRequestMessage.
224
+ //
225
+ // # Semantics
226
+ //
227
+ // This message indicates whether the Helper successfully:
228
+ //
229
+ // - stored or updated the requested share version
230
+ // - applied the retention policy (keepList)
231
+ //
232
+ // # Idempotency
233
+ //
234
+ // Multiple identical requests SHOULD produce identical responses.
235
+ message StoreShareResponseMessage {
236
+
237
+ // Result of processing the request.
238
+ //
239
+ // Indicates success or failure of the storage/update operation.
240
+ DeRecResult result = 1;
241
+
242
+ // Identifier of the secret to which this response refers.
243
+ //
244
+ // Echoed from the corresponding StoreShareRequestMessage so the Owner can
245
+ // correlate responses with the correct secret without inspecting the share
246
+ // bytes.
247
+ uint64 secretId = 2;
248
+
249
+ // Version number from the corresponding request.
250
+ //
251
+ // This allows the sender to correlate responses with requests.
252
+ uint32 version = 3;
253
+
254
+ // Timestamp indicating when this message was created.
255
+ //
256
+ // Used for observability, replay detection, and timeout handling.
257
+ google.protobuf.Timestamp timestamp = 4;
258
+
259
+ // Identity of the replica that produced this response.
260
+ //
261
+ // Present only when the corresponding request was replica-bound
262
+ // (`shareAlgorithm == SHARE_ALGORITHM_REPLICA_SECRET`); absent on
263
+ // helper responses, which carry no replica identity in either
264
+ // direction.
265
+ //
266
+ // # Why the requester needs it
267
+ //
268
+ // Every member of a replica group answers on the same `channelId`, and
269
+ // `secretId` and `version` are echoed identically by all of them. Two
270
+ // members responding to one publish are otherwise indistinguishable —
271
+ // the requester cannot tell whether both acknowledged or one
272
+ // acknowledged twice, and so cannot track a sharing round per member.
273
+ optional uint64 replicaId = 5;
274
+ }