docs: finalize rvbox v1 design and implementation plan
This commit is contained in:
+39
-31
@@ -2,35 +2,34 @@ syntax = "proto3";
|
||||
|
||||
package rvbox.v1;
|
||||
|
||||
option go_package = "github.com/rvbox/rvbox/gen/go/rvbox/v1;rvboxv1";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "rvbox/v1/common.proto";
|
||||
|
||||
option go_package = "github.com/rvbox/rvbox/gen/go/rvbox/v1;rvboxv1";
|
||||
|
||||
// One AgentEnvelope is carried in one binary WebSocket message.
|
||||
message AgentEnvelope {
|
||||
// Empty only for ClientHello. All other envelopes are fenced to a session.
|
||||
string session_id = 1;
|
||||
uint64 session_generation = 2;
|
||||
string message_id = 3;
|
||||
|
||||
oneof payload {
|
||||
ClientHello client_hello = 10;
|
||||
ServerWelcome server_welcome = 11;
|
||||
CommandDispatch command_dispatch = 12;
|
||||
CommandAccepted command_accepted = 13;
|
||||
CommandEvent command_event = 14;
|
||||
EventAck event_ack = 15;
|
||||
StdinWrite stdin_write = 16;
|
||||
CloseStdin close_stdin = 17;
|
||||
SignalCommand signal_command = 18;
|
||||
ScriptChunk script_chunk = 19;
|
||||
ScriptCommit script_commit = 20;
|
||||
ClientCapacity client_capacity = 21;
|
||||
ReconcileRequest reconcile_request = 22;
|
||||
ReconcileSnapshot reconcile_snapshot = 23;
|
||||
AgentError error = 24;
|
||||
ClientOutputTruncated client_output_truncated = 25;
|
||||
ClientHello client_hello = 3;
|
||||
ServerWelcome server_welcome = 4;
|
||||
CommandDispatch command_dispatch = 5;
|
||||
CommandAccepted command_accepted = 6;
|
||||
CommandEvent command_event = 7;
|
||||
EventAck event_ack = 8;
|
||||
StdinWrite stdin_write = 9;
|
||||
CloseStdin close_stdin = 10;
|
||||
SignalCommand signal_command = 11;
|
||||
ScriptChunk script_chunk = 12;
|
||||
ScriptCommit script_commit = 13;
|
||||
ClientCapacity client_capacity = 14;
|
||||
ReconcileRequest reconcile_request = 15;
|
||||
ReconcileSnapshot reconcile_snapshot = 16;
|
||||
AgentError error = 17;
|
||||
ReconcileResult reconcile_result = 18;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +42,8 @@ message ClientHello {
|
||||
string architecture = 5;
|
||||
string daemon_cwd = 6;
|
||||
repeated ShellType supported_shells = 7;
|
||||
string reconnect_uuid = 8;
|
||||
// Generated once and persisted in the client state directory.
|
||||
string client_instance_id = 8;
|
||||
uint32 max_running_commands = 9;
|
||||
uint32 max_queued_commands = 10;
|
||||
google.protobuf.Timestamp sent_at = 11;
|
||||
@@ -61,6 +61,7 @@ message CommandDispatch {
|
||||
uint64 target_session_generation = 3;
|
||||
google.protobuf.Timestamp issue_time = 4;
|
||||
ExecutionSpec spec = 5;
|
||||
google.protobuf.Timestamp queue_expiry_time = 6;
|
||||
}
|
||||
|
||||
message CommandAccepted {
|
||||
@@ -122,23 +123,30 @@ message ReconcileTarget {
|
||||
string issue_uuid = 1;
|
||||
uint64 last_server_event_seq = 2;
|
||||
uint64 command_revision = 3;
|
||||
bytes immutable_request_sha256 = 4;
|
||||
}
|
||||
|
||||
// Sent only for requests in ReconcileRequest; server-confirmed terminal history
|
||||
// is intentionally not requested.
|
||||
message ReconcileSnapshot {
|
||||
string issue_uuid = 1;
|
||||
bool known_to_client = 2;
|
||||
CommandLifecycle lifecycle = 3;
|
||||
uint64 last_client_event_seq = 4;
|
||||
uint64 command_revision = 5;
|
||||
// The complete set still retained by the client, including non-terminal and
|
||||
// terminal-but-unacknowledged commands.
|
||||
repeated ReconcileCommandState retained_commands = 1;
|
||||
}
|
||||
|
||||
// Sent before retained replay data when an offline client had to rotate
|
||||
// unacknowledged output to remain within its hard spool limits.
|
||||
message ClientOutputTruncated {
|
||||
message ReconcileCommandState {
|
||||
string issue_uuid = 1;
|
||||
OutputTruncation truncation = 2;
|
||||
CommandLifecycle lifecycle = 2;
|
||||
uint64 last_client_event_seq = 3;
|
||||
uint64 command_revision = 4;
|
||||
// True only for a matching UUID/request hash in the compact tombstone ledger.
|
||||
bool tombstoned = 5;
|
||||
bytes immutable_request_sha256 = 6;
|
||||
}
|
||||
|
||||
// Sent after the server durably compares a complete snapshot and before it
|
||||
// dispatches new work on the session. Repetition is idempotent.
|
||||
message ReconcileResult {
|
||||
repeated string terminate_local_issue_uuids = 1;
|
||||
repeated string discard_local_terminal_issue_uuids = 2;
|
||||
}
|
||||
|
||||
message AgentError {
|
||||
|
||||
@@ -2,11 +2,11 @@ syntax = "proto3";
|
||||
|
||||
package rvbox.v1;
|
||||
|
||||
option go_package = "github.com/rvbox/rvbox/gen/go/rvbox/v1;rvboxv1";
|
||||
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
option go_package = "github.com/rvbox/rvbox/gen/go/rvbox/v1;rvboxv1";
|
||||
|
||||
// An inclusive protocol-version range advertised during registration.
|
||||
message ProtocolRange {
|
||||
uint32 major = 1;
|
||||
@@ -52,6 +52,8 @@ enum CommandLifecycle {
|
||||
COMMAND_TERMINATED = 7;
|
||||
COMMAND_CANCELLED = 8;
|
||||
COMMAND_INTERRUPTED = 9;
|
||||
COMMAND_EXPIRED = 10;
|
||||
COMMAND_REJECTED = 11;
|
||||
}
|
||||
|
||||
enum StreamKind {
|
||||
@@ -109,16 +111,23 @@ message CommandRecord {
|
||||
ExecutionSpec spec = 5;
|
||||
CommandLifecycle lifecycle = 6;
|
||||
uint64 last_event_seq = 7;
|
||||
int32 exit_code = 8;
|
||||
optional int32 exit_code = 8;
|
||||
google.protobuf.Timestamp terminal_time = 9;
|
||||
bool output_truncated = 10;
|
||||
uint64 retained_compressed_bytes = 11;
|
||||
google.protobuf.Timestamp queue_expiry_time = 12;
|
||||
bool output_incomplete = 13;
|
||||
// Present when lifecycle is COMMAND_REJECTED.
|
||||
ControlError rejection = 14;
|
||||
uint64 command_revision = 15;
|
||||
bool late_after_expiry = 16;
|
||||
}
|
||||
|
||||
message LifecycleChange {
|
||||
CommandLifecycle lifecycle = 1;
|
||||
int32 exit_code = 2;
|
||||
optional int32 exit_code = 2;
|
||||
string detail = 3;
|
||||
uint64 command_revision = 4;
|
||||
}
|
||||
|
||||
// data is compressed according to compression. uncompressed_size is mandatory
|
||||
@@ -132,15 +141,16 @@ message OutputChunk {
|
||||
}
|
||||
|
||||
message ResourceSnapshot {
|
||||
uint64 resident_memory_bytes = 1;
|
||||
uint64 virtual_memory_bytes = 2;
|
||||
optional uint64 resident_memory_bytes = 1;
|
||||
optional uint64 virtual_memory_bytes = 2;
|
||||
google.protobuf.Duration cpu_time = 3;
|
||||
uint64 read_bytes = 4;
|
||||
uint64 write_bytes = 5;
|
||||
string process_state = 6;
|
||||
string wait_reason = 7;
|
||||
optional uint64 read_bytes = 4;
|
||||
optional uint64 write_bytes = 5;
|
||||
optional string process_state = 6;
|
||||
optional string wait_reason = 7;
|
||||
bool suspected_hung = 8;
|
||||
string diagnostic_detail = 9;
|
||||
optional string current_cwd = 10;
|
||||
}
|
||||
|
||||
enum OutputTruncationSource {
|
||||
@@ -148,19 +158,31 @@ enum OutputTruncationSource {
|
||||
OUTPUT_TRUNCATION_SOURCE_CLIENT_SPOOL = 1;
|
||||
OUTPUT_TRUNCATION_SOURCE_SERVER_COMMAND_WINDOW = 2;
|
||||
OUTPUT_TRUNCATION_SOURCE_SERVER_CLIENT_CAP = 3;
|
||||
OUTPUT_TRUNCATION_SOURCE_CLIENT_OVERLOAD = 4;
|
||||
OUTPUT_TRUNCATION_SOURCE_SERVER_GLOBAL_CAP = 5;
|
||||
}
|
||||
|
||||
// Persistent query metadata for a missing contiguous event range. It is not a
|
||||
// CommandEvent and therefore does not consume an event_seq.
|
||||
// Metadata for missing output. Server-side retention supplies the optional
|
||||
// event range. Client output discarded before wire sequence assignment omits
|
||||
// the range and carries this as a normally sequenced CommandEvent.
|
||||
message OutputTruncation {
|
||||
uint64 first_removed_event_seq = 1;
|
||||
uint64 last_removed_event_seq = 2;
|
||||
uint64 removed_compressed_bytes = 3;
|
||||
optional uint64 first_removed_event_seq = 1;
|
||||
optional uint64 last_removed_event_seq = 2;
|
||||
// Absent when bytes were discarded before compression.
|
||||
optional uint64 removed_compressed_bytes = 3;
|
||||
uint64 removed_uncompressed_bytes = 4;
|
||||
string reason = 5;
|
||||
OutputTruncationSource source = 6;
|
||||
}
|
||||
|
||||
// Indicates that capture ended without a provably complete byte stream. It is
|
||||
// sequenced before the terminal lifecycle event but does not claim an invented
|
||||
// event or byte range.
|
||||
message OutputIncomplete {
|
||||
repeated StreamKind streams = 1;
|
||||
string reason = 2;
|
||||
}
|
||||
|
||||
message StdinAcknowledgement {
|
||||
uint64 write_seq = 1;
|
||||
bool stdin_closed = 2;
|
||||
@@ -173,6 +195,7 @@ message SignalResult {
|
||||
bool graceful_delivery_attempted = 3;
|
||||
bool forced_termination_used = 4;
|
||||
string detail = 5;
|
||||
uint64 command_revision = 6;
|
||||
}
|
||||
|
||||
message ScriptUploadStatus {
|
||||
@@ -188,12 +211,14 @@ message CommandEvent {
|
||||
uint64 event_seq = 2;
|
||||
google.protobuf.Timestamp observed_at = 3;
|
||||
oneof payload {
|
||||
LifecycleChange lifecycle = 10;
|
||||
OutputChunk output = 11;
|
||||
ResourceSnapshot resource = 12;
|
||||
StdinAcknowledgement stdin_ack = 13;
|
||||
SignalResult signal_result = 14;
|
||||
ScriptUploadStatus script_status = 15;
|
||||
LifecycleChange lifecycle = 4;
|
||||
OutputChunk output = 5;
|
||||
ResourceSnapshot resource = 6;
|
||||
StdinAcknowledgement stdin_ack = 7;
|
||||
SignalResult signal_result = 8;
|
||||
ScriptUploadStatus script_status = 9;
|
||||
OutputTruncation output_truncation = 10;
|
||||
OutputIncomplete output_incomplete = 11;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +234,7 @@ message ControlError {
|
||||
PROTOCOL_ERROR = 7;
|
||||
TRANSIENT = 8;
|
||||
INTERNAL = 9;
|
||||
CODE_ALREADY_EXECUTED = 10;
|
||||
}
|
||||
Code code = 1;
|
||||
string message = 2;
|
||||
|
||||
+112
-15
@@ -2,22 +2,27 @@ syntax = "proto3";
|
||||
|
||||
package rvbox.v1;
|
||||
|
||||
option go_package = "github.com/rvbox/rvbox/gen/go/rvbox/v1;rvboxv1";
|
||||
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "rvbox/v1/common.proto";
|
||||
|
||||
option go_package = "github.com/rvbox/rvbox/gen/go/rvbox/v1;rvboxv1";
|
||||
|
||||
service Control {
|
||||
rpc ListClients(ListClientsRequest) returns (ListClientsResponse);
|
||||
rpc GetClient(GetClientRequest) returns (GetClientResponse);
|
||||
rpc ListCommands(ListCommandsRequest) returns (ListCommandsResponse);
|
||||
rpc GetCommand(GetCommandRequest) returns (GetCommandResponse);
|
||||
rpc RunCommand(RunCommandRequest) returns (RunCommandResponse);
|
||||
rpc RunCommandAndFollow(RunCommandRequest) returns (stream CommandEvent);
|
||||
rpc FollowCommand(FollowCommandRequest) returns (stream CommandEvent);
|
||||
rpc FollowCommand(FollowCommandRequest) returns (stream FollowCommandResponse);
|
||||
rpc AppendStdin(AppendStdinRequest) returns (AppendStdinResponse);
|
||||
rpc CloseStdin(CloseStdinRequest) returns (CloseStdinResponse);
|
||||
rpc SignalCommand(ControlSignalCommandRequest) returns (ControlSignalCommandResponse);
|
||||
rpc GetOutput(GetOutputRequest) returns (GetOutputResponse);
|
||||
rpc ListStorageIncidents(ListStorageIncidentsRequest) returns (ListStorageIncidentsResponse);
|
||||
rpc RepairStorageIncident(RepairStorageIncidentRequest) returns (RepairStorageIncidentResponse);
|
||||
rpc AcknowledgeStorageIncident(AcknowledgeStorageIncidentRequest) returns (AcknowledgeStorageIncidentResponse);
|
||||
rpc AuthorizeClientTakeover(AuthorizeClientTakeoverRequest) returns (AuthorizeClientTakeoverResponse);
|
||||
}
|
||||
|
||||
message ClientSummary {
|
||||
@@ -32,6 +37,10 @@ message ClientSummary {
|
||||
string daemon_version = 9;
|
||||
string daemon_cwd = 10;
|
||||
repeated ShellType supported_shells = 11;
|
||||
string client_instance_id = 12;
|
||||
// Most recently rejected different instance while this client is live.
|
||||
string pending_instance_id = 13;
|
||||
google.protobuf.Timestamp pending_instance_seen_at = 14;
|
||||
}
|
||||
|
||||
message ListClientsRequest {
|
||||
@@ -50,7 +59,6 @@ message GetClientRequest {
|
||||
|
||||
message GetClientResponse {
|
||||
ClientSummary client = 1;
|
||||
ControlError error = 2;
|
||||
}
|
||||
|
||||
message ListCommandsRequest {
|
||||
@@ -63,7 +71,6 @@ message ListCommandsRequest {
|
||||
message ListCommandsResponse {
|
||||
repeated CommandRecord commands = 1;
|
||||
string next_page_token = 2;
|
||||
ControlError error = 3;
|
||||
}
|
||||
|
||||
message GetCommandRequest {
|
||||
@@ -74,7 +81,6 @@ message GetCommandRequest {
|
||||
message GetCommandResponse {
|
||||
CommandRecord command = 1;
|
||||
ResourceSnapshot latest_resource = 2;
|
||||
ControlError error = 3;
|
||||
}
|
||||
|
||||
// For script execution, script_content contains the bytes whose descriptor is
|
||||
@@ -83,12 +89,15 @@ message RunCommandRequest {
|
||||
string target_client_id = 1;
|
||||
ExecutionSpec spec = 2;
|
||||
bytes script_content = 3;
|
||||
// Becomes issue_uuid when supplied; generated by the server when omitted.
|
||||
string request_id = 4;
|
||||
// Omitted uses the server default; zero explicitly requests no expiry.
|
||||
google.protobuf.Duration queue_ttl = 5;
|
||||
}
|
||||
|
||||
message RunCommandResponse {
|
||||
string issue_uuid = 1;
|
||||
CommandLifecycle lifecycle = 2;
|
||||
ControlError error = 3;
|
||||
}
|
||||
|
||||
message FollowCommandRequest {
|
||||
@@ -98,37 +107,47 @@ message FollowCommandRequest {
|
||||
bool include_existing = 4;
|
||||
}
|
||||
|
||||
message FollowCommandResponse {
|
||||
oneof item {
|
||||
CommandEvent event = 1;
|
||||
// Server retention metadata; does not advance the client event cursor.
|
||||
RetentionTruncation retention_truncation = 2;
|
||||
}
|
||||
// Set for a client event; server-created retention uses its own recorded_at.
|
||||
google.protobuf.Timestamp server_receipt_time = 3;
|
||||
}
|
||||
|
||||
message AppendStdinRequest {
|
||||
string client_id = 1;
|
||||
string issue_uuid = 2;
|
||||
bytes data = 3;
|
||||
bool append_newline = 4;
|
||||
string request_id = 5;
|
||||
}
|
||||
|
||||
message AppendStdinResponse {
|
||||
uint64 write_seq = 1;
|
||||
ControlError error = 2;
|
||||
}
|
||||
|
||||
message CloseStdinRequest {
|
||||
string client_id = 1;
|
||||
string issue_uuid = 2;
|
||||
string request_id = 3;
|
||||
}
|
||||
|
||||
message CloseStdinResponse {
|
||||
uint64 write_seq = 1;
|
||||
ControlError error = 2;
|
||||
}
|
||||
|
||||
message ControlSignalCommandRequest {
|
||||
string client_id = 1;
|
||||
string issue_uuid = 2;
|
||||
SignalKind signal = 3;
|
||||
string request_id = 4;
|
||||
}
|
||||
|
||||
message ControlSignalCommandResponse {
|
||||
uint64 command_revision = 1;
|
||||
ControlError error = 2;
|
||||
}
|
||||
|
||||
message GetOutputRequest {
|
||||
@@ -136,13 +155,91 @@ message GetOutputRequest {
|
||||
string issue_uuid = 2;
|
||||
repeated StreamKind streams = 3;
|
||||
uint64 after_event_seq = 4;
|
||||
uint32 page_size = 5;
|
||||
uint64 max_bytes = 5;
|
||||
string page_token = 6;
|
||||
}
|
||||
|
||||
// An uncompressed slice of one persisted output event. Opaque pagination may
|
||||
// resume within an event; event_byte_offset identifies that position.
|
||||
message OutputSlice {
|
||||
uint64 event_seq = 1;
|
||||
google.protobuf.Timestamp observed_at = 2;
|
||||
StreamKind stream = 3;
|
||||
bytes data = 4;
|
||||
uint64 event_byte_offset = 5;
|
||||
bool end_of_event = 6;
|
||||
google.protobuf.Timestamp server_receipt_time = 7;
|
||||
}
|
||||
|
||||
message RetentionTruncation {
|
||||
OutputTruncation truncation = 1;
|
||||
google.protobuf.Timestamp server_recorded_at = 2;
|
||||
}
|
||||
|
||||
message GetOutputResponse {
|
||||
repeated CommandEvent events = 1;
|
||||
repeated OutputSlice output = 1;
|
||||
string next_page_token = 2;
|
||||
bool output_truncated = 3;
|
||||
ControlError error = 4;
|
||||
repeated OutputTruncation truncations = 5;
|
||||
repeated RetentionTruncation truncations = 4;
|
||||
OutputIncomplete incomplete = 5;
|
||||
}
|
||||
|
||||
enum StorageIncidentState {
|
||||
STORAGE_INCIDENT_STATE_UNSPECIFIED = 0;
|
||||
STORAGE_INCIDENT_STATE_OPEN = 1;
|
||||
STORAGE_INCIDENT_STATE_REPAIRED = 2;
|
||||
STORAGE_INCIDENT_STATE_ACKNOWLEDGED = 3;
|
||||
}
|
||||
|
||||
message StorageIncident {
|
||||
string incident_id = 1;
|
||||
google.protobuf.Timestamp detected_at = 2;
|
||||
google.protobuf.Timestamp resolved_at = 3;
|
||||
StorageIncidentState state = 4;
|
||||
string scope = 5;
|
||||
string client_id = 6;
|
||||
string issue_uuid = 7;
|
||||
string summary = 8;
|
||||
bool data_loss = 9;
|
||||
bool automatically_repairable = 10;
|
||||
}
|
||||
|
||||
message ListStorageIncidentsRequest {
|
||||
bool include_resolved = 1;
|
||||
uint32 page_size = 2;
|
||||
string page_token = 3;
|
||||
}
|
||||
|
||||
message ListStorageIncidentsResponse {
|
||||
repeated StorageIncident incidents = 1;
|
||||
string next_page_token = 2;
|
||||
}
|
||||
|
||||
message RepairStorageIncidentRequest {
|
||||
string incident_id = 1;
|
||||
string request_id = 2;
|
||||
}
|
||||
|
||||
message RepairStorageIncidentResponse {
|
||||
StorageIncident incident = 1;
|
||||
}
|
||||
|
||||
message AcknowledgeStorageIncidentRequest {
|
||||
string incident_id = 1;
|
||||
string note = 2;
|
||||
string request_id = 3;
|
||||
}
|
||||
|
||||
message AcknowledgeStorageIncidentResponse {
|
||||
StorageIncident incident = 1;
|
||||
}
|
||||
|
||||
message AuthorizeClientTakeoverRequest {
|
||||
string client_id = 1;
|
||||
string client_instance_id = 2;
|
||||
string request_id = 3;
|
||||
}
|
||||
|
||||
message AuthorizeClientTakeoverResponse {
|
||||
google.protobuf.Timestamp expires_at = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user