revault_api 0.5.1-aarch64-linux → 0.6.1-aarch64-linux

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,808 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Revault
4
+ module Bindings
5
+ # Public reciprocal exchange status. Verification is a local trust decision; no management capability or private key is returned.
6
+ class ContactExchangeStatus
7
+ # Random identifier of the saved exchange.
8
+ attr_reader :id
9
+ # Pinned HTTPS relay origin.
10
+ attr_reader :relay
11
+ # Invitation URL to share only with the intended recipient.
12
+ attr_reader :invitation
13
+ # Signed claimed inviter email, not independently verified by the relay.
14
+ attr_reader :inviter_email
15
+ # Signed claimed intended recipient email.
16
+ attr_reader :recipient_email
17
+ # Full shared fingerprint to compare independently; empty until both contributions are available.
18
+ attr_reader :fingerprint
19
+ # Signed invitation expiry in Unix milliseconds.
20
+ attr_reader :expires_ms
21
+ # Whether both signed public key bundles are locally pinned.
22
+ attr_reader :accepted
23
+ # Whether this Vault independently verified and saved the contact.
24
+ attr_reader :verified
25
+ # Local saved contact name, or empty before verification.
26
+ attr_reader :contact_name
27
+ # Whether the relay operation needs retrying; locally saved state is retained.
28
+ attr_reader :relay_pending
29
+ # Creates a domain value from named fields.
30
+ def initialize(id: '', relay: '', invitation: '', inviter_email: '', recipient_email: '', fingerprint: '', expires_ms: 0, accepted: false, verified: false, contact_name: '', relay_pending: false) = (@id = id; @relay = relay; @invitation = invitation; @inviter_email = inviter_email; @recipient_email = recipient_email; @fingerprint = fingerprint; @expires_ms = expires_ms; @accepted = accepted; @verified = verified; @contact_name = contact_name; @relay_pending = relay_pending)
31
+ end
32
+
33
+ # Ordered ContactExchangeStatus values returned by the corresponding list operation.
34
+ class ContactExchangeStatusList
35
+ # Ordered ContactExchangeStatus values returned by the corresponding list operation.
36
+ attr_reader :values
37
+ # Creates a domain value from named fields.
38
+ def initialize(values: []) = (@values = values)
39
+ end
40
+
41
+ # Metadata for one file, directory, or symbolic link stored at a lockbox path.
42
+ class LockboxEntry
43
+ # Absolute lockbox path of the stored entry.
44
+ attr_reader :path
45
+ # Filesystem kind: file, directory, or symbolic link.
46
+ attr_reader :kind
47
+ # Logical file length in bytes; zero for directories.
48
+ attr_reader :length
49
+ # Portable Unix permission bits stored with the entry.
50
+ attr_reader :permissions
51
+ # Creates a domain value from named fields.
52
+ def initialize(path: '', kind: 0, length: 0, permissions: 0) = (@path = path; @kind = kind; @length = length; @permissions = permissions)
53
+ end
54
+
55
+ # Ordered lockbox entries selected by a list operation.
56
+ class LockboxEntryList
57
+ # Ordered lockbox entries selected by a list operation.
58
+ attr_reader :entries
59
+ # Creates a domain value from named fields.
60
+ def initialize(entries: []) = (@entries = entries)
61
+ end
62
+
63
+ # The metadata found for a lockbox path, or no value when the path is absent.
64
+ class OptionalLockboxEntry
65
+ # The metadata found for a lockbox path, or no value when the path is absent.
66
+ attr_reader :value
67
+ # Creates a domain value from named fields.
68
+ def initialize(value: nil) = (@value = value)
69
+ end
70
+
71
+ # Ordered names or identifiers returned by a vault list operation.
72
+ class StringList
73
+ # Ordered names or identifiers returned by a vault list operation.
74
+ attr_reader :values
75
+ # Creates a domain value from named fields.
76
+ def initialize(values: []) = (@values = values)
77
+ end
78
+
79
+ # A source and destination pair used to rename a variable or form record atomically.
80
+ class PathMove
81
+ # Existing variable name or form-record path to rename.
82
+ attr_reader :source
83
+ # New variable name or form-record path.
84
+ attr_reader :destination
85
+ # Creates a domain value from named fields.
86
+ def initialize(source: '', destination: '') = (@source = source; @destination = destination)
87
+ end
88
+
89
+ # Atomic variable or form-record renames supplied to a move operation.
90
+ class PathMoveList
91
+ # Atomic variable or form-record renames supplied to a move operation.
92
+ attr_reader :values
93
+ # Creates a domain value from named fields.
94
+ def initialize(values: []) = (@values = values)
95
+ end
96
+
97
+ # One named input in a reusable form definition, including its display label and sensitivity kind.
98
+ class FormField
99
+ # Stable field identifier used when reading and writing records.
100
+ attr_reader :id
101
+ # Human-readable label presented to a person entering data.
102
+ attr_reader :label
103
+ # Field kind that determines validation and secret handling.
104
+ attr_reader :kind
105
+ # Whether a record must provide a value for this field.
106
+ attr_reader :required
107
+ # Multiline guidance captured by this field definition revision.
108
+ attr_reader :description
109
+ # Whether guidance is present, including explicitly empty text.
110
+ attr_reader :has_description
111
+ # Creates a domain value from named fields.
112
+ def initialize(id: '', label: '', kind: '', required: false, description: '', has_description: false) = (@id = id; @label = label; @kind = kind; @required = required; @description = description; @has_description = has_description)
113
+ end
114
+
115
+ # Ordered field definitions supplied when defining a form.
116
+ class FormFieldList
117
+ # Ordered field definitions supplied when defining a form.
118
+ attr_reader :values
119
+ # Creates a domain value from named fields.
120
+ def initialize(values: []) = (@values = values)
121
+ end
122
+
123
+ # A versioned form schema used to validate and label structured records in a lockbox.
124
+ class FormDefinition
125
+ # Stable identifier shared by every revision of this form type.
126
+ attr_reader :type_id
127
+ # Short name used to resolve the current form revision.
128
+ attr_reader :form_alias
129
+ # Monotonically increasing revision number.
130
+ attr_reader :revision
131
+ # Human-readable name shown for this form.
132
+ attr_reader :name
133
+ # Explanation shown to people completing the form.
134
+ attr_reader :description
135
+ # Ordered inputs accepted by this form revision.
136
+ attr_reader :fields
137
+ # Creates a domain value from named fields.
138
+ def initialize(type_id: '', form_alias: '', revision: 0, name: '', description: '', fields: []) = (@type_id = type_id; @form_alias = form_alias; @revision = revision; @name = name; @description = description; @fields = fields)
139
+ end
140
+
141
+ # Ordered FormDefinition values returned by the corresponding list operation.
142
+ class FormDefinitionList
143
+ # Ordered FormDefinition values returned by the corresponding list operation.
144
+ attr_reader :values
145
+ # Creates a domain value from named fields.
146
+ def initialize(values: []) = (@values = values)
147
+ end
148
+
149
+ # The current value and sensitivity metadata for one field in a stored form record.
150
+ class FormValue
151
+ # Identifier of the form field that owns this value.
152
+ attr_reader :field_id
153
+ # Display label captured from the form revision.
154
+ attr_reader :label
155
+ # Field kind captured from the form revision.
156
+ attr_reader :kind
157
+ # Plain value, or an empty string when the field is secret.
158
+ attr_reader :value
159
+ # Whether the value must be read through a scoped secret callback.
160
+ attr_reader :secret
161
+ # Creates a domain value from named fields.
162
+ def initialize(field_id: '', label: '', kind: '', value: '', secret: false) = (@field_id = field_id; @label = label; @kind = kind; @value = value; @secret = secret)
163
+ end
164
+
165
+ # A named structured record stored at a lockbox path and tied to a form-definition revision.
166
+ class FormRecord
167
+ # Absolute lockbox path that identifies the record.
168
+ attr_reader :path
169
+ # Human-readable name assigned to this record.
170
+ attr_reader :name
171
+ # Stable identifier of the record's form type.
172
+ attr_reader :type_id
173
+ # Alias of the form definition used by the record.
174
+ attr_reader :definition_alias
175
+ # Exact form revision against which the record was created.
176
+ attr_reader :definition_revision
177
+ # Ordered non-secret field metadata and values.
178
+ attr_reader :values
179
+ # Multiline context specific to this record.
180
+ attr_reader :description
181
+ # Whether the record description is present, including empty text.
182
+ attr_reader :has_description
183
+ # Creates a domain value from named fields.
184
+ def initialize(path: '', name: '', type_id: '', definition_alias: '', definition_revision: 0, values: [], description: '', has_description: false) = (@path = path; @name = name; @type_id = type_id; @definition_alias = definition_alias; @definition_revision = definition_revision; @values = values; @description = description; @has_description = has_description)
185
+ end
186
+
187
+ # Ordered FormRecord values returned by the corresponding list operation.
188
+ class FormRecordList
189
+ # Ordered FormRecord values returned by the corresponding list operation.
190
+ attr_reader :values
191
+ # Creates a domain value from named fields.
192
+ def initialize(values: []) = (@values = values)
193
+ end
194
+
195
+ # The form record found at a lockbox path, or no value when absent.
196
+ class OptionalFormRecord
197
+ # The form record found at a lockbox path, or no value when absent.
198
+ attr_reader :value
199
+ # Creates a domain value from named fields.
200
+ def initialize(value: nil) = (@value = value)
201
+ end
202
+
203
+ # The requested non-secret form value, or no value when the field is absent.
204
+ class OptionalFormValue
205
+ # The requested non-secret form value, or no value when the field is absent.
206
+ attr_reader :value
207
+ # Creates a domain value from named fields.
208
+ def initialize(value: nil) = (@value = value)
209
+ end
210
+
211
+ # The files and metadata recovered, or found damaged, while inspecting or salvaging a lockbox.
212
+ class RecoveryReport
213
+ # Files whose complete contents remain recoverable.
214
+ attr_reader :intact_files
215
+ # Number of completely recoverable files.
216
+ attr_reader :intact_file_count
217
+ # Number of files for which only some content is recoverable.
218
+ attr_reader :partial_files
219
+ # Number of encrypted records that failed validation.
220
+ attr_reader :corrupt_records
221
+ # Whether a usable table of contents was recovered.
222
+ attr_reader :toc_recovered
223
+ # Whether variable metadata was recovered.
224
+ attr_reader :variables_recovered
225
+ # Number of recovered variables.
226
+ attr_reader :variable_count
227
+ # Whether form definitions and records were recovered.
228
+ attr_reader :forms_recovered
229
+ # Number of recovered form definitions.
230
+ attr_reader :form_definition_count
231
+ # Number of recovered form records.
232
+ attr_reader :form_record_count
233
+ # Creates a domain value from named fields.
234
+ def initialize(intact_files: [], intact_file_count: 0, partial_files: 0, corrupt_records: 0, toc_recovered: false, variables_recovered: false, variable_count: 0, forms_recovered: false, form_definition_count: 0, form_record_count: 0) = (@intact_files = intact_files; @intact_file_count = intact_file_count; @partial_files = partial_files; @corrupt_records = corrupt_records; @toc_recovered = toc_recovered; @variables_recovered = variables_recovered; @variable_count = variable_count; @forms_recovered = forms_recovered; @form_definition_count = form_definition_count; @form_record_count = form_record_count)
235
+ end
236
+
237
+ # One password or contact credential that can unlock a lockbox content key.
238
+ class KeySlot
239
+ # Stable slot identifier used when removing this access method.
240
+ attr_reader :id
241
+ # Access method, such as password or contact key.
242
+ attr_reader :protection
243
+ # Cryptographic algorithm protecting the content key.
244
+ attr_reader :algorithm
245
+ # Creates a domain value from named fields.
246
+ def initialize(id: 0, protection: '', algorithm: '') = (@id = id; @protection = protection; @algorithm = algorithm)
247
+ end
248
+
249
+ # Ordered KeySlot values returned by the corresponding list operation.
250
+ class KeySlotList
251
+ # Ordered KeySlot values returned by the corresponding list operation.
252
+ attr_reader :values
253
+ # Creates a domain value from named fields.
254
+ def initialize(values: []) = (@values = values)
255
+ end
256
+
257
+ # Current capacity, occupancy, hit, and miss counters for an open lockbox cache.
258
+ class CacheStats
259
+ # Maximum decoded-page memory permitted for the cache.
260
+ attr_reader :limit_bytes
261
+ # Decoded-page memory currently held by the cache.
262
+ attr_reader :used_bytes
263
+ # Number of decoded pages currently cached.
264
+ attr_reader :entries
265
+ # Reads served by an already decoded page.
266
+ attr_reader :hits
267
+ # Reads that required decoding another page.
268
+ attr_reader :misses
269
+ # Creates a domain value from named fields.
270
+ def initialize(limit_bytes: 0, used_bytes: 0, entries: 0, hits: 0, misses: 0) = (@limit_bytes = limit_bytes; @used_bytes = used_bytes; @entries = entries; @hits = hits; @misses = misses)
271
+ end
272
+
273
+ # Time spent reading host files and preparing encrypted pages during the latest import work.
274
+ class ImportStats
275
+ # Nanoseconds spent reading host filesystem metadata, as decimal text.
276
+ attr_reader :host_stat_nanos
277
+ # Nanoseconds spent reading host file content, as decimal text.
278
+ attr_reader :host_read_nanos
279
+ # Nanoseconds spent preparing encrypted records, as decimal text.
280
+ attr_reader :frame_prepare_nanos
281
+ # Nanoseconds spent writing encrypted pages, as decimal text.
282
+ attr_reader :page_write_nanos
283
+ # Creates a domain value from named fields.
284
+ def initialize(host_stat_nanos: '', host_read_nanos: '', frame_prepare_nanos: '', page_write_nanos: '') = (@host_stat_nanos = host_stat_nanos; @host_read_nanos = host_read_nanos; @frame_prepare_nanos = frame_prepare_nanos; @page_write_nanos = page_write_nanos)
285
+ end
286
+
287
+ # One logical object recorded inside an inspected encrypted lockbox page.
288
+ class PageObject
289
+ # Object identifier recorded in the encrypted page.
290
+ attr_reader :id
291
+ # Kind of logical object stored in the page.
292
+ attr_reader :kind
293
+ # Encrypted object payload length in bytes.
294
+ attr_reader :payload_len
295
+ # Creates a domain value from named fields.
296
+ def initialize(id: 0, kind: '', payload_len: 0) = (@id = id; @kind = kind; @payload_len = payload_len)
297
+ end
298
+
299
+ # Layout and utilization details for one encrypted page in a lockbox archive.
300
+ class PageInspection
301
+ # Byte offset at which the page begins in the archive.
302
+ attr_reader :offset
303
+ # Identifier stored in the page header.
304
+ attr_reader :page_id
305
+ # Commit sequence that wrote this page.
306
+ attr_reader :sequence
307
+ # Total encoded page size in bytes.
308
+ attr_reader :page_size
309
+ # Encrypted body length in bytes.
310
+ attr_reader :encrypted_body_len
311
+ # Unused capacity remaining in the page.
312
+ attr_reader :unused_bytes
313
+ # Number of logical objects stored in the page.
314
+ attr_reader :object_count
315
+ # Logical objects discovered in the page.
316
+ attr_reader :objects
317
+ # Creates a domain value from named fields.
318
+ def initialize(offset: 0, page_id: 0, sequence: 0, page_size: 0, encrypted_body_len: 0, unused_bytes: 0, object_count: 0, objects: []) = (@offset = offset; @page_id = page_id; @sequence = sequence; @page_size = page_size; @encrypted_body_len = encrypted_body_len; @unused_bytes = unused_bytes; @object_count = object_count; @objects = objects)
319
+ end
320
+
321
+ # Ordered PageInspection values returned by the corresponding list operation.
322
+ class PageInspectionList
323
+ # Ordered PageInspection values returned by the corresponding list operation.
324
+ attr_reader :values
325
+ # Creates a domain value from named fields.
326
+ def initialize(values: []) = (@values = values)
327
+ end
328
+
329
+ # Header, owner-signature, and key-slot information read from a lockbox file without opening its contents.
330
+ class FileInspection
331
+ # Stable binary identifier read from the lockbox header.
332
+ attr_reader :lockbox_id
333
+ # Whether the archive header passed structural validation.
334
+ attr_reader :header_readable
335
+ # Latest readable access-key directory generation.
336
+ attr_reader :key_directory_generation
337
+ # Number of readable redundant key-directory copies.
338
+ attr_reader :key_directory_copy_count
339
+ # Whether commits require an owner signature.
340
+ attr_reader :owner_signed
341
+ # Password and contact access methods found in the header.
342
+ attr_reader :key_slots
343
+ # Creates a domain value from named fields.
344
+ def initialize(lockbox_id: [], header_readable: false, key_directory_generation: 0, key_directory_copy_count: 0, owner_signed: false, key_slots: []) = (@lockbox_id = lockbox_id; @header_readable = header_readable; @key_directory_generation = key_directory_generation; @key_directory_copy_count = key_directory_copy_count; @owner_signed = owner_signed; @key_slots = key_slots)
345
+ end
346
+
347
+ # One active or retired generation of the contact keys belonging to a named vault profile.
348
+ class ProfileGeneration
349
+ # Generation number used to address this key version.
350
+ attr_reader :index
351
+ # Lifecycle state, such as active or retired.
352
+ attr_reader :status
353
+ # Fingerprint of this generation's contact public key.
354
+ attr_reader :contact_fingerprint
355
+ # Creation time in Unix milliseconds.
356
+ attr_reader :created_at_unix_ms
357
+ # Retirement time in Unix milliseconds when retired.
358
+ attr_reader :retired_at_unix_ms
359
+ # Whether a retirement time is present.
360
+ attr_reader :has_retired_at
361
+ # Creates a domain value from named fields.
362
+ def initialize(index: 0, status: '', contact_fingerprint: [], created_at_unix_ms: 0, retired_at_unix_ms: 0, has_retired_at: false) = (@index = index; @status = status; @contact_fingerprint = contact_fingerprint; @created_at_unix_ms = created_at_unix_ms; @retired_at_unix_ms = retired_at_unix_ms; @has_retired_at = has_retired_at)
363
+ end
364
+
365
+ # The active generation and rotation history for a named vault profile.
366
+ class ProfileHistory
367
+ # Vault profile name whose generations are listed.
368
+ attr_reader :name
369
+ # Generation number currently used for new access grants.
370
+ attr_reader :active_generation
371
+ # Active and retired contact-key generations.
372
+ attr_reader :generations
373
+ # Creates a domain value from named fields.
374
+ def initialize(name: '', active_generation: 0, generations: []) = (@name = name; @active_generation = active_generation; @generations = generations)
375
+ end
376
+
377
+ # A local Vault alias mapping a normalized name to a stable lockbox identity; resolution does not open the target.
378
+ class LockboxAlias
379
+ # Case-sensitive normalized NFC alias name.
380
+ attr_reader :name
381
+ # Stable binary target identity; verify it when opening the resolved path.
382
+ attr_reader :lockbox_id
383
+ # Creates a domain value from named fields.
384
+ def initialize(name: '', lockbox_id: []) = (@name = name; @lockbox_id = lockbox_id)
385
+ end
386
+
387
+ # Ordered LockboxAlias values returned by the corresponding list operation.
388
+ class LockboxAliasList
389
+ # Ordered LockboxAlias values returned by the corresponding list operation.
390
+ attr_reader :values
391
+ # Creates a domain value from named fields.
392
+ def initialize(values: []) = (@values = values)
393
+ end
394
+
395
+ # A lockbox identifier and host path remembered by the local vault for later discovery.
396
+ class KnownLockbox
397
+ # Stable binary identifier of the remembered lockbox.
398
+ attr_reader :lockbox_id
399
+ # Last known host filesystem path of the lockbox.
400
+ attr_reader :path
401
+ # Most recent observation time in Unix milliseconds.
402
+ attr_reader :last_seen_unix_ms
403
+ # Creates a domain value from named fields.
404
+ def initialize(lockbox_id: [], path: '', last_seen_unix_ms: 0) = (@lockbox_id = lockbox_id; @path = path; @last_seen_unix_ms = last_seen_unix_ms)
405
+ end
406
+
407
+ # Ordered KnownLockbox values returned by the corresponding list operation.
408
+ class KnownLockboxList
409
+ # Ordered KnownLockbox values returned by the corresponding list operation.
410
+ attr_reader :values
411
+ # Creates a domain value from named fields.
412
+ def initialize(values: []) = (@values = values)
413
+ end
414
+
415
+ # A local human-readable label attached to one lockbox access slot.
416
+ class AccessSlotLabel
417
+ # Lockbox whose access slot is labelled.
418
+ attr_reader :lockbox_id
419
+ # Stable identifier of the labelled access slot.
420
+ attr_reader :slot_id
421
+ # Local human-readable label for the access slot.
422
+ attr_reader :name
423
+ # Last label update time in Unix milliseconds.
424
+ attr_reader :updated_at_unix_ms
425
+ # Creates a domain value from named fields.
426
+ def initialize(lockbox_id: [], slot_id: 0, name: '', updated_at_unix_ms: 0) = (@lockbox_id = lockbox_id; @slot_id = slot_id; @name = name; @updated_at_unix_ms = updated_at_unix_ms)
427
+ end
428
+
429
+ # Ordered AccessSlotLabel values returned by the corresponding list operation.
430
+ class AccessSlotLabelList
431
+ # Ordered AccessSlotLabel values returned by the corresponding list operation.
432
+ attr_reader :values
433
+ # Creates a domain value from named fields.
434
+ def initialize(values: []) = (@values = values)
435
+ end
436
+
437
+ # A logical or physical byte range emitted while walking the contents of a lockbox.
438
+ class StreamChunk
439
+ # Lockbox file path to which this byte range belongs.
440
+ attr_reader :path
441
+ # Logical byte offset within the file.
442
+ attr_reader :file_offset
443
+ # Logical range length in bytes.
444
+ attr_reader :length
445
+ # Archive byte offset, when physical streaming is requested.
446
+ attr_reader :physical_offset
447
+ # Whether the range represents a sparse zero-filled extent.
448
+ attr_reader :sparse
449
+ # File bytes for a populated logical range.
450
+ attr_reader :data
451
+ # Creates a domain value from named fields.
452
+ def initialize(path: '', file_offset: 0, length: 0, physical_offset: 0, sparse: false, data: []) = (@path = path; @file_offset = file_offset; @length = length; @physical_offset = physical_offset; @sparse = sparse; @data = data)
453
+ end
454
+
455
+ # Ordered StreamChunk values returned by the corresponding list operation.
456
+ class StreamChunkList
457
+ # Ordered StreamChunk values returned by the corresponding list operation.
458
+ attr_reader :values
459
+ # Creates a domain value from named fields.
460
+ def initialize(values: []) = (@values = values)
461
+ end
462
+
463
+ # The workload and worker policies currently applied to an open lockbox.
464
+ class RuntimeOptions
465
+ # I/O workload policy used to tune page access.
466
+ attr_reader :workload_profile
467
+ # Worker scheduling policy and effective parallelism.
468
+ attr_reader :worker_policy
469
+ # Creates a domain value from named fields.
470
+ def initialize(workload_profile: '', worker_policy: '') = (@workload_profile = workload_profile; @worker_policy = worker_policy)
471
+ end
472
+
473
+ # The name and sensitivity classification of a variable stored in a lockbox.
474
+ class Variable
475
+ # Name used to address the variable in the lockbox.
476
+ attr_reader :name
477
+ # Whether the value is ordinary text or a protected secret.
478
+ attr_reader :sensitivity
479
+ # Multiline description stored with this variable.
480
+ attr_reader :description
481
+ # Whether the variable description is present, including empty text.
482
+ attr_reader :has_description
483
+ # Creates a domain value from named fields.
484
+ def initialize(name: '', sensitivity: '', description: '', has_description: false) = (@name = name; @sensitivity = sensitivity; @description = description; @has_description = has_description)
485
+ end
486
+
487
+ # Ordered Variable values returned by the corresponding list operation.
488
+ class VariableList
489
+ # Ordered Variable values returned by the corresponding list operation.
490
+ attr_reader :values
491
+ # Creates a domain value from named fields.
492
+ def initialize(values: []) = (@values = values)
493
+ end
494
+
495
+ # A text lookup that distinguishes an absent value from an empty string.
496
+ class OptionalString
497
+ # A text lookup that distinguishes an absent value from an empty string.
498
+ attr_reader :present
499
+ # A text lookup that distinguishes an absent value from an empty string.
500
+ attr_reader :value
501
+ # Creates a domain value from named fields.
502
+ def initialize(present: false, value: '') = (@present = present; @value = value)
503
+ end
504
+
505
+ # Whether a lockbox is owner-signed and, when available, the signing-key fingerprint.
506
+ class OwnerInspection
507
+ # Whether the lockbox requires owner-signed commits.
508
+ attr_reader :signed
509
+ # Owner signing-key fingerprint when one is configured.
510
+ attr_reader :fingerprint
511
+ # Whether an owner fingerprint is available.
512
+ attr_reader :has_fingerprint
513
+ # Creates a domain value from named fields.
514
+ def initialize(signed: false, fingerprint: '', has_fingerprint: false) = (@signed = signed; @fingerprint = fingerprint; @has_fingerprint = has_fingerprint)
515
+ end
516
+
517
+ # A named recipient public key stored in the local vault address book.
518
+ class Contact
519
+ # Local address-book name of the contact.
520
+ attr_reader :name
521
+ # Serialized contact public key used to grant lockbox access.
522
+ attr_reader :key
523
+ # Creates a domain value from named fields.
524
+ def initialize(name: '', key: []) = (@name = name; @key = key)
525
+ end
526
+
527
+ # Ordered Contact values returned by the corresponding list operation.
528
+ class ContactList
529
+ # Ordered Contact values returned by the corresponding list operation.
530
+ attr_reader :values
531
+ # Creates a domain value from named fields.
532
+ def initialize(values: []) = (@values = values)
533
+ end
534
+
535
+ # Ordered ProfileHistory values returned by the corresponding list operation.
536
+ class ProfileHistoryList
537
+ # Ordered ProfileHistory values returned by the corresponding list operation.
538
+ attr_reader :values
539
+ # Creates a domain value from named fields.
540
+ def initialize(values: []) = (@values = values)
541
+ end
542
+
543
+ # A lockbox key currently held by the local Session Agent, identified by lockbox and path.
544
+ class AgentEntry
545
+ # Stable lockbox identifier for the cached key.
546
+ attr_reader :id
547
+ # Host path associated with the cached lockbox key.
548
+ attr_reader :path
549
+ # Creates a domain value from named fields.
550
+ def initialize(id: '', path: '') = (@id = id; @path = path)
551
+ end
552
+
553
+ # Ordered AgentEntry values returned by the corresponding list operation.
554
+ class AgentEntryList
555
+ # Ordered AgentEntry values returned by the corresponding list operation.
556
+ attr_reader :values
557
+ # Creates a domain value from named fields.
558
+ def initialize(values: []) = (@values = values)
559
+ end
560
+
561
+ # The host capabilities used to protect cached secrets across suspend and sleep.
562
+ class SleepSupport
563
+ # Whether suspend notification support is compiled for this host.
564
+ attr_reader :suspend_notifications
565
+ # Whether sleep inhibition support is compiled for this host.
566
+ attr_reader :sleep_inhibition
567
+ # Whether this build includes the host integration; this is not runtime watcher readiness.
568
+ attr_reader :supported
569
+ # Whether the current compatible Session Agent reports an active suspend cache watcher; false when absent or unavailable. Notification delivery is platform-dependent.
570
+ attr_reader :cache_clearing_active
571
+ # Creates a domain value from named fields.
572
+ def initialize(suspend_notifications: false, sleep_inhibition: false, supported: false, cache_clearing_active: false) = (@suspend_notifications = suspend_notifications; @sleep_inhibition = sleep_inhibition; @supported = supported; @cache_clearing_active = cache_clearing_active)
573
+ end
574
+
575
+ # Availability and configuration of the platform credential store used for the Vault passphrase.
576
+ class PlatformStatus
577
+ # Whether a usable platform credential store exists.
578
+ attr_reader :supported
579
+ # Whether the user disabled platform credential store integration.
580
+ attr_reader :disabled
581
+ # Application-specific scope used to isolate the stored password.
582
+ attr_reader :scope
583
+ # Platform credential store backend in use.
584
+ attr_reader :backend
585
+ # Credential item name used by the backend.
586
+ attr_reader :item
587
+ # Creates a domain value from named fields.
588
+ def initialize(supported: false, disabled: false, scope: '', backend: '', item: '') = (@supported = supported; @disabled = disabled; @scope = scope; @backend = backend; @item = item)
589
+ end
590
+
591
+ # One text result returned by the native API.
592
+ class StringValue
593
+ # One text result returned by the native API.
594
+ attr_reader :value
595
+ # Creates a domain value from named fields.
596
+ def initialize(value: '') = (@value = value)
597
+ end
598
+
599
+ # The version, size, checksum, and creation time of an exported local-vault backup.
600
+ class VaultBackupManifest
601
+ # Backup container format version.
602
+ attr_reader :format_version
603
+ # Backup creation time in Unix milliseconds.
604
+ attr_reader :created_at_unix_ms
605
+ # Metadata-vault filename stored in the backup.
606
+ attr_reader :vault_file_name
607
+ # Encrypted vault payload size in bytes.
608
+ attr_reader :vault_size
609
+ # Lowercase SHA-256 digest of the encrypted vault payload.
610
+ attr_reader :vault_sha256
611
+ # Creates a domain value from named fields.
612
+ def initialize(format_version: 0, created_at_unix_ms: 0, vault_file_name: '', vault_size: 0, vault_sha256: '') = (@format_version = format_version; @created_at_unix_ms = created_at_unix_ms; @vault_file_name = vault_file_name; @vault_size = vault_size; @vault_sha256 = vault_sha256)
613
+ end
614
+
615
+ # Structured category, version, guidance, and artifact context for the most recent native failure.
616
+ class ErrorDetails
617
+ # Stable error category suitable for programmatic handling.
618
+ attr_reader :category
619
+ # Kind of archive or vault artifact involved in the failure.
620
+ attr_reader :artifact_kind
621
+ # Format version read from the failing artifact.
622
+ attr_reader :found_version
623
+ # Newest format version supported by this library.
624
+ attr_reader :supported_version
625
+ # Human-readable explanation of the failure.
626
+ attr_reader :message
627
+ # Suggested corrective action for the caller or user.
628
+ attr_reader :guidance
629
+ # Creates a domain value from named fields.
630
+ def initialize(category: '', artifact_kind: '', found_version: 0, supported_version: 0, message: '', guidance: '') = (@category = category; @artifact_kind = artifact_kind; @found_version = found_version; @supported_version = supported_version; @message = message; @guidance = guidance)
631
+ end
632
+
633
+ end
634
+
635
+ module Internal
636
+ # FlatBuffer reader and input encoder used only by the FFI layer.
637
+ module DomainCodec
638
+ module_function
639
+
640
+ SCHEMA = {
641
+ 'ContactExchangeStatus' => [[:id, 'string'], [:relay, 'string'], [:invitation, 'string'], [:inviter_email, 'string'], [:recipient_email, 'string'], [:fingerprint, 'string'], [:expires_ms, 'ulong'], [:accepted, 'bool'], [:verified, 'bool'], [:contact_name, 'string'], [:relay_pending, 'bool']],
642
+ 'ContactExchangeStatusList' => [[:values, '[revault.internal.ContactExchangeStatus]']],
643
+ 'LockboxEntry' => [[:path, 'string'], [:kind, 'revault.internal.LockboxEntryKind'], [:length, 'ulong'], [:permissions, 'uint']],
644
+ 'LockboxEntryList' => [[:entries, '[revault.internal.LockboxEntry]']],
645
+ 'OptionalLockboxEntry' => [[:value, 'revault.internal.LockboxEntry']],
646
+ 'StringList' => [[:values, '[string]']],
647
+ 'PathMove' => [[:source, 'string'], [:destination, 'string']],
648
+ 'PathMoveList' => [[:values, '[revault.internal.PathMove]']],
649
+ 'FormField' => [[:id, 'string'], [:label, 'string'], [:kind, 'string'], [:required, 'bool'], [:description, 'string'], [:has_description, 'bool']],
650
+ 'FormFieldList' => [[:values, '[revault.internal.FormField]']],
651
+ 'FormDefinition' => [[:type_id, 'string'], [:alias, 'string'], [:revision, 'uint'], [:name, 'string'], [:description, 'string'], [:fields, '[revault.internal.FormField]']],
652
+ 'FormDefinitionList' => [[:values, '[revault.internal.FormDefinition]']],
653
+ 'FormValue' => [[:field_id, 'string'], [:label, 'string'], [:kind, 'string'], [:value, 'string'], [:secret, 'bool']],
654
+ 'FormRecord' => [[:path, 'string'], [:name, 'string'], [:type_id, 'string'], [:definition_alias, 'string'], [:definition_revision, 'uint'], [:values, '[revault.internal.FormValue]'], [:description, 'string'], [:has_description, 'bool']],
655
+ 'FormRecordList' => [[:values, '[revault.internal.FormRecord]']],
656
+ 'OptionalFormRecord' => [[:value, 'revault.internal.FormRecord']],
657
+ 'OptionalFormValue' => [[:value, 'revault.internal.FormValue']],
658
+ 'RecoveryReport' => [[:intact_files, '[revault.internal.LockboxEntry]'], [:intact_file_count, 'ulong'], [:partial_files, 'ulong'], [:corrupt_records, 'ulong'], [:toc_recovered, 'bool'], [:variables_recovered, 'bool'], [:variable_count, 'ulong'], [:forms_recovered, 'bool'], [:form_definition_count, 'ulong'], [:form_record_count, 'ulong']],
659
+ 'KeySlot' => [[:id, 'ulong'], [:protection, 'string'], [:algorithm, 'string']],
660
+ 'KeySlotList' => [[:values, '[revault.internal.KeySlot]']],
661
+ 'CacheStats' => [[:limit_bytes, 'ulong'], [:used_bytes, 'ulong'], [:entries, 'ulong'], [:hits, 'ulong'], [:misses, 'ulong']],
662
+ 'ImportStats' => [[:host_stat_nanos, 'string'], [:host_read_nanos, 'string'], [:frame_prepare_nanos, 'string'], [:page_write_nanos, 'string']],
663
+ 'PageObject' => [[:id, 'ulong'], [:kind, 'string'], [:payload_len, 'ulong']],
664
+ 'PageInspection' => [[:offset, 'ulong'], [:page_id, 'ulong'], [:sequence, 'ulong'], [:page_size, 'ulong'], [:encrypted_body_len, 'ulong'], [:unused_bytes, 'ulong'], [:object_count, 'ulong'], [:objects, '[revault.internal.PageObject]']],
665
+ 'PageInspectionList' => [[:values, '[revault.internal.PageInspection]']],
666
+ 'FileInspection' => [[:lockbox_id, '[ubyte]'], [:header_readable, 'bool'], [:key_directory_generation, 'ulong'], [:key_directory_copy_count, 'ulong'], [:owner_signed, 'bool'], [:key_slots, '[revault.internal.KeySlot]']],
667
+ 'ProfileGeneration' => [[:index, 'uint'], [:status, 'string'], [:contact_fingerprint, '[ubyte]'], [:created_at_unix_ms, 'ulong'], [:retired_at_unix_ms, 'ulong'], [:has_retired_at, 'bool']],
668
+ 'ProfileHistory' => [[:name, 'string'], [:active_generation, 'uint'], [:generations, '[revault.internal.ProfileGeneration]']],
669
+ 'LockboxAlias' => [[:name, 'string'], [:lockbox_id, '[ubyte]']],
670
+ 'LockboxAliasList' => [[:values, '[revault.internal.LockboxAlias]']],
671
+ 'KnownLockbox' => [[:lockbox_id, '[ubyte]'], [:path, 'string'], [:last_seen_unix_ms, 'ulong']],
672
+ 'KnownLockboxList' => [[:values, '[revault.internal.KnownLockbox]']],
673
+ 'AccessSlotLabel' => [[:lockbox_id, '[ubyte]'], [:slot_id, 'ulong'], [:name, 'string'], [:updated_at_unix_ms, 'ulong']],
674
+ 'AccessSlotLabelList' => [[:values, '[revault.internal.AccessSlotLabel]']],
675
+ 'StreamChunk' => [[:path, 'string'], [:file_offset, 'ulong'], [:length, 'ulong'], [:physical_offset, 'ulong'], [:sparse, 'bool'], [:data, '[ubyte]']],
676
+ 'StreamChunkList' => [[:values, '[revault.internal.StreamChunk]']],
677
+ 'RuntimeOptions' => [[:workload_profile, 'string'], [:worker_policy, 'string']],
678
+ 'Variable' => [[:name, 'string'], [:sensitivity, 'string'], [:description, 'string'], [:has_description, 'bool']],
679
+ 'VariableList' => [[:values, '[revault.internal.Variable]']],
680
+ 'OptionalString' => [[:present, 'bool'], [:value, 'string']],
681
+ 'OwnerInspection' => [[:signed, 'bool'], [:fingerprint, 'string'], [:has_fingerprint, 'bool']],
682
+ 'Contact' => [[:name, 'string'], [:key, '[ubyte]']],
683
+ 'ContactList' => [[:values, '[revault.internal.Contact]']],
684
+ 'ProfileHistoryList' => [[:values, '[revault.internal.ProfileHistory]']],
685
+ 'AgentEntry' => [[:id, 'string'], [:path, 'string']],
686
+ 'AgentEntryList' => [[:values, '[revault.internal.AgentEntry]']],
687
+ 'SleepSupport' => [[:suspend_notifications, 'bool'], [:sleep_inhibition, 'bool'], [:supported, 'bool'], [:cache_clearing_active, 'bool']],
688
+ 'PlatformStatus' => [[:supported, 'bool'], [:disabled, 'bool'], [:scope, 'string'], [:backend, 'string'], [:item, 'string']],
689
+ 'StringValue' => [[:value, 'string']],
690
+ 'VaultBackupManifest' => [[:format_version, 'uint'], [:created_at_unix_ms, 'ulong'], [:vault_file_name, 'string'], [:vault_size, 'ulong'], [:vault_sha256, 'string']],
691
+ 'ErrorDetails' => [[:category, 'string'], [:artifact_kind, 'string'], [:found_version, 'uint'], [:supported_version, 'uint'], [:message, 'string'], [:guidance, 'string']]
692
+ }.freeze
693
+
694
+ def decode(name, bytes)
695
+ table(name, bytes.b, bytes.unpack1('V'))
696
+ end
697
+
698
+ def table(name, bytes, position)
699
+ values = {}
700
+ SCHEMA.fetch(name).each_with_index do |(field, type), index|
701
+ location = field_location(bytes, position, index)
702
+ public_field = field == :alias ? :form_alias : field
703
+ values[public_field] = read_value(bytes, location, type)
704
+ end
705
+ Bindings.const_get(name).new(**values)
706
+ end
707
+
708
+ def field_location(bytes, table_position, index)
709
+ vtable = table_position - bytes.unpack1('l<', offset: table_position)
710
+ vtable_length = bytes.unpack1('v', offset: vtable)
711
+ entry = vtable + 4 + (index * 2)
712
+ return nil if entry + 2 > vtable + vtable_length
713
+ offset = bytes.unpack1('v', offset: entry)
714
+ offset.zero? ? nil : table_position + offset
715
+ end
716
+
717
+ def read_value(bytes, location, type)
718
+ return default_value(type) unless location
719
+ if type.start_with?('[')
720
+ read_vector(bytes, location, type[1...-1])
721
+ elsif SCHEMA.key?(type.split('.').last)
722
+ table(type.split('.').last, bytes, location + bytes.unpack1('V', offset: location))
723
+ else
724
+ read_scalar(bytes, location, type)
725
+ end
726
+ end
727
+
728
+ def read_vector(bytes, location, type)
729
+ vector = location + bytes.unpack1('V', offset: location)
730
+ length = bytes.unpack1('V', offset: vector)
731
+ start = vector + 4
732
+ return bytes.byteslice(start, length) if type == 'ubyte'
733
+ Array.new(length) do |index|
734
+ element = start + (index * 4)
735
+ if type == 'string'
736
+ read_string(bytes, element)
737
+ elsif SCHEMA.key?(type.split('.').last)
738
+ table(type.split('.').last, bytes, element + bytes.unpack1('V', offset: element))
739
+ else
740
+ read_scalar(bytes, element, type)
741
+ end
742
+ end
743
+ end
744
+
745
+ def read_scalar(bytes, location, type)
746
+ case type
747
+ when 'string' then read_string(bytes, location)
748
+ when 'bool', 'ubyte' then bytes.getbyte(location) != 0
749
+ when 'ulong' then bytes.unpack1('Q<', offset: location)
750
+ else bytes.unpack1('V', offset: location)
751
+ end
752
+ end
753
+
754
+ def read_string(bytes, location)
755
+ value = location + bytes.unpack1('V', offset: location)
756
+ bytes.byteslice(value + 4, bytes.unpack1('V', offset: value)).force_encoding(Encoding::UTF_8)
757
+ end
758
+
759
+ def default_value(type)
760
+ return [] if type.start_with?('[')
761
+ return '' if type == 'string'
762
+ return false if type == 'bool'
763
+ return 0 if %w[uint ulong ubyte].include?(type) || type.end_with?('LockboxEntryKind')
764
+ nil
765
+ end
766
+
767
+ def encode_path_moves(values) = encode_table_vector(values, :path_move)
768
+ def encode_form_fields(values) = encode_table_vector(values, :form_field)
769
+
770
+ def encode_table_vector(values, kind)
771
+ bytes = [0].pack('V')
772
+ append_vtable(bytes, [4], 8)
773
+ root = align(bytes); bytes << [root - 4, 0].pack('V2')
774
+ patch_u32(bytes, 0, root)
775
+ vector = align(bytes); patch_u32(bytes, root + 4, vector - (root + 4)); bytes << [values.length].pack('V') << ("\0" * (values.length * 4))
776
+ values.each_with_index do |value, index|
777
+ position = kind == :path_move ? append_path_move(bytes, value) : append_form_field(bytes, value)
778
+ element = vector + 4 + (index * 4); patch_u32(bytes, element, position - element)
779
+ end
780
+ bytes
781
+ end
782
+
783
+ def append_path_move(bytes, value)
784
+ vtable = append_vtable(bytes, [4, 8], 12); table = align(bytes); bytes << [table - vtable, 0, 0].pack('V3')
785
+ append_string_field(bytes, table + 4, value.source); append_string_field(bytes, table + 8, value.destination); table
786
+ end
787
+
788
+ def append_form_field(bytes, value)
789
+ vtable = append_vtable(bytes, [4, 8, 12, 16, 20, 24], 28); table = align(bytes); bytes << [table - vtable, 0, 0, 0].pack('V4') << [value.required ? 1 : 0].pack('C') << "\0\0\0" << [0].pack('V') << [value.has_description ? 1 : 0].pack('C') << "\0\0\0"
790
+ append_string_field(bytes, table + 4, value.id); append_string_field(bytes, table + 8, value.label); append_string_field(bytes, table + 12, value.kind); append_string_field(bytes, table + 20, value.description); table
791
+ end
792
+
793
+ def append_vtable(bytes, offsets, object_size)
794
+ align(bytes, 2); position = bytes.bytesize; bytes << [4 + (offsets.length * 2), object_size, *offsets].pack('v*'); position
795
+ end
796
+
797
+ def append_string_field(bytes, field, value)
798
+ target = align(bytes); patch_u32(bytes, field, target - field); bytes << [value.bytesize].pack('V') << value.b << "\0"
799
+ end
800
+
801
+ def align(bytes, alignment = 4)
802
+ bytes << "\0" until (bytes.bytesize % alignment).zero?; bytes.bytesize
803
+ end
804
+
805
+ def patch_u32(bytes, offset, value) = bytes[offset, 4] = [value].pack('V')
806
+ end
807
+ end
808
+ end