syntax = "proto3";

package iop;

import "proto/iop/runtime.proto";

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

// PolicyRule is a placeholder for future edge-level routing/resource constraints.
message PolicyRule {
  string name       = 1;
  string expression = 2;
  map<string, string> params = 3;
}

// ScheduleRequest is a reserved legacy tombstone. The original direct Node
// scheduling fields are retired; the message name is kept only to keep the
// field numbers reserved so they cannot be reused as an active contract.
// Future orchestration must go through Edge-owned runtime state.
message ScheduleRequest {
  reserved 1 to 4;
  reserved "job_id", "target", "policies", "metadata";
}

// ScheduleResponse is a reserved legacy tombstone. The original node
// address/token fields are retired; future scheduling should be reworked
// around Edge-owned runtime state instead of bypassing Edge.
message ScheduleResponse {
  reserved 1 to 3;
  reserved "node_id", "address", "token";
}

message ClientHelloRequest {
  string client_id = 1;
  string client_version = 2;
}

message ClientHelloResponse {
  bool ready = 1;
  string protocol = 2;
  int64 server_time_unix_nano = 3;
  string message = 4;
}

// EdgeHelloRequest is sent by Edge to Control Plane immediately after a
// Control Plane-Edge wire connection is established. It describes the Edge
// itself and must not become a direct Node registration or scheduling contract.
message EdgeHelloRequest {
  string edge_id = 1;
  string edge_name = 2;
  string version = 3;
  repeated string capabilities = 4;
  map<string, string> metadata = 5;
}

// EdgeHelloResponse acknowledges Edge enrollment on the Control Plane-Edge
// wire. Rejection details stay at the Edge boundary rather than exposing Node
// scheduling decisions.
message EdgeHelloResponse {
  bool accepted = 1;
  string protocol = 2;
  int64 server_time_unix_nano = 3;
  string message = 4;
  string reason = 5;
  PrincipalProjection principal_projection = 6;
}

// ProjectedPrincipalToken is a secret-free verifier entry reserved for the
// authenticated Control Plane-Edge credential-plane rollout. The digest is a
// SHA-256 hex value; raw IOP tokens are never carried by this message.
message ProjectedPrincipalToken {
  string token_digest_sha256 = 1;
  string principal_ref = 2;
  string principal_alias = 3;
  string token_ref = 4;
  uint64 token_revision = 5;
}

// ProjectedPrincipalRoute is a secret-free principal route binding. It names
// the selected credential slot and revision but never carries ciphertext,
// plaintext provider credentials, or runtime authorization headers.
message ProjectedPrincipalRoute {
  string route_id = 1;
  string route_alias = 2;
  string principal_ref = 3;
  string credential_slot_ref = 4;
  string profile_id = 5;
  string upstream_model = 6;
  string resource_selector = 7;
  uint64 route_revision = 8;
  uint64 credential_revision = 9;
}

// PrincipalProjection is an immutable, generation-fenced authorization and
// routing snapshot. These value types are dormant until the Control
// Plane-Edge transport provides authenticated peer identity and integrity.
message PrincipalProjection {
  uint64 generation = 1;
  int64 issued_at_unix_nano = 2;
  int64 expires_at_unix_nano = 3;
  repeated ProjectedPrincipalToken tokens = 4;
  repeated ProjectedPrincipalRoute routes = 5;
}

// PrincipalProjectionApplyRequest and PrincipalProjectionApplyResponse reserve
// the future apply operation payload without registering a parser or handler
// on the current unauthenticated Control Plane-Edge connection.
message PrincipalProjectionApplyRequest {
  PrincipalProjection projection = 1;
}

message PrincipalProjectionApplyResponse {
  bool applied = 1;
  uint64 accepted_generation = 2;
  string reason = 3;
}

// EdgeStatusRequest asks a connected Edge to report its Edge-owned node
// registry snapshot. It carries only a correlation id; the Control Plane does
// not address, connect to, or schedule Node directly through this contract.
message EdgeStatusRequest {
  string request_id = 1;
}

// EdgeNodeSnapshot is a surface-neutral view of a node owned by the Edge. It
// only mirrors what the Edge service exposes and must not carry Node address,
// token, or scheduling fields.
message EdgeNodeSnapshot {
  string node_id = 1;
  string alias = 2;
  string label = 3;
  bool connected = 4;
  NodeConfigPayload config = 5;
  // provider_snapshots uses the runtime ProviderSnapshot wire name for node
  // resources/providers. category distinguishes API and local inference.
  repeated ProviderSnapshot provider_snapshots = 6;
}

// EdgeStatusResponse returns the Edge-owned node snapshot list in reply to an
// EdgeStatusRequest. The Control Plane observes this snapshot rather than
// replicating the Edge-local registry.
message EdgeStatusResponse {
  reserved 9;
  reserved "domain_agents";
  string request_id = 1;
  string edge_id = 2;
  string edge_name = 3;
  int64 observed_time_unix_nano = 4;
  repeated EdgeNodeSnapshot nodes = 5;
  map<string, string> metadata = 6;
  string error = 7;
  repeated EdgeCapabilitySummary capabilities = 8;
}

message EdgeCapabilitySummary {
  string kind = 1;
  bool available = 2;
  string status = 3;
  string summary = 4;
}

message EdgeCommandRequest {
  string request_id = 1;
  string command_id = 2;
  string target_selector = 3;
  string operation = 4;
  map<string, string> parameters = 5;
}

message EdgeCommandResponse {
  string request_id = 1;
  string command_id = 2;
  string edge_id = 3;
  string status = 4;
  string summary = 5;
  string error = 6;
}

message EdgeCommandEvent {
  string command_id = 1;
  string edge_id = 2;
  string phase = 3;
  string summary = 4;
  int64 occurred_at = 5;
}
