syntax = "proto3";

package iop;

option go_package = "iop/proto/gen/iop";

// AgentLocalKind identifies the semantic role of one local-control envelope.
enum AgentLocalKind {
  AGENT_LOCAL_KIND_UNSPECIFIED = 0;
  AGENT_LOCAL_KIND_REQUEST = 1;
  AGENT_LOCAL_KIND_RESPONSE = 2;
  AGENT_LOCAL_KIND_EVENT = 3;
  AGENT_LOCAL_KIND_ERROR = 4;
}

// AgentLocalEnvelope is the only protobuf message carried by the local
// proto-socket. The explicit kind and typed payload must agree.
message AgentLocalEnvelope {
  uint32 protocol_version = 1;
  AgentLocalKind kind = 2;
  string message_id = 3;
  string correlation_id = 4;
  uint64 event_sequence = 5;
  string operation = 6;

  reserved 7 to 9;

  oneof payload {
    AgentLocalRequest request = 10;
    AgentLocalResponse response = 11;
    AgentLocalEvent event = 12;
    AgentLocalError error = 13;
  }

  reserved 14 to 19;
}

// AgentLocalRequest contains exactly one typed operation payload. A replay
// cursor is optional and is meaningful only when replay_daemon_id is present.
message AgentLocalRequest {
  string command_id = 1;
  string replay_daemon_id = 2;
  optional uint64 replay_after_sequence = 3;

  reserved 4 to 9;

  oneof payload {
    AgentLocalReadRequest read = 10;
    AgentLocalProjectRequest project = 11;
    AgentLocalClientRequest client = 12;
  }

  reserved 13 to 19;
}

// AgentLocalReadRequest selects a safe host projection. Empty selectors are
// allowed only for runtime.status.
message AgentLocalReadRequest {
  string project_id = 1;
  string work_unit_id = 2;
  string client_kind = 3;
}

// AgentLocalProjectRequest carries immutable shared-runtime lifecycle inputs.
message AgentLocalProjectRequest {
  string project_id = 1;
  string workspace_id = 2;
  string milestone_id = 3;
}

// AgentLocalClientRequest reserves the typed S15 client-process input without
// enabling those operations in the S11 service.
message AgentLocalClientRequest {
  string client_kind = 1;
  string capability = 2;
}

// AgentLocalResponse carries either a coherent snapshot or one accepted
// mutation result, plus any retained events requested by the replay cursor.
message AgentLocalResponse {
  string command_id = 1;
  uint64 state_revision = 2;
  string snapshot_marker = 3;
  string replay_daemon_id = 4;
  uint64 replay_cursor = 5;

  reserved 6 to 9;

  oneof payload {
    AgentLocalSnapshot snapshot = 10;
    AgentLocalMutationResult mutation = 11;
  }

  repeated AgentLocalEvent replay_events = 12;
  reserved 13 to 19;
}

// AgentLocalSnapshot is a client-neutral, path-free status projection.
message AgentLocalSnapshot {
  string daemon_id = 1;
  uint64 state_revision = 2;
  uint64 replay_cursor = 3;
  string subject_id = 4;
  string state = 5;
  string summary = 6;
  repeated AgentLocalStatusEntry entries = 7;
}

message AgentLocalStatusEntry {
  string kind = 1;
  string subject_id = 2;
  string state = 3;
  string summary = 4;
}

message AgentLocalMutationResult {
  bool accepted = 1;
  string subject_id = 2;
  string state = 3;
  string summary = 4;
}

// AgentLocalEvent is retained in monotonically increasing sequence order.
message AgentLocalEvent {
  uint64 event_sequence = 1;
  string event_type = 2;
  string subject_id = 3;
  uint64 state_revision = 4;
  AgentLocalMutationResult mutation = 5;
}

// AgentLocalError exposes only stable, bounded, path-free diagnostics.
message AgentLocalError {
  string code = 1;
  string safe_message = 2;
  bool retryable = 3;
  string correlation_id = 4;
  uint64 replay_floor = 5;
  bool snapshot_required = 6;
  string snapshot_marker = 7;
}
