// Proposed contract, version 1. Status: proposal for review, not confirmed design.
//
// Every system implements this service once: it publishes, from its code, the capabilities its roles may contain,
// the entitlement features it offers and the agent tools its MCP server exposes.
// Callers: access (validates a role's capabilities against the union of the catalogs, req 1002, 1006),
// farm (validates an entitlement's feature, req 68.3), moochat (validates a tool's required capabilities, req 122).
// Deadline: 2 s. Cached by the caller; refreshed after a deploy.
// The callers listed are authentication only (decided 2026-11-11): each RPC below names who may call it and what
// it sees, and refuses anyone else with PERMISSION_DENIED.
// x-moonitoring-callers: access, farm, moochat
// x-moonitoring-requirements: 1002, 1006, 68.3, 122, 141, 144.8
syntax = "proto3";

package moonitoring.common.catalog.v1;

import "google/protobuf/timestamp.proto";

// The catalog a system publishes from its code.
service CatalogService {
  // Returns the catalog of the system that serves the call.
  // Callers: access, farm and moochat. Sees: the same catalog for every caller; it holds no customer data.
  rpc GetCatalog(GetCatalogRequest) returns (GetCatalogResponse);
}

message GetCatalogRequest {
  // When set, the server answers NOT_MODIFIED semantics by returning an empty catalog with the same version.
  string known_version = 1;
}

message GetCatalogResponse {
  Catalog catalog = 1;
}

message Catalog {
  // Short name of the system, e.g. farm.
  string system = 1;
  // Release of the system that published it, e.g. 1.4.0.
  string version = 2;
  // Capabilities for Organization roles (req 1002), named <system>.<resource>.<action>.
  repeated Capability organization_capabilities = 3;
  // Capabilities for staff roles (req 1006).
  repeated Capability staff_capabilities = 4;
  // Entitlement features (req 68.3), named <system>.<feature>.
  repeated Feature features = 5;
  // Agent tools of the system's MCP server (req 122).
  repeated Tool tools = 6;
  google.protobuf.Timestamp published_at = 7;
  // Event types the system lets leave the platform, offered by the Webhooks API (req 141.4, 144.8).
  repeated ExternalEventType external_events = 8;
}

message ExternalEventType {
  // Type with its version, e.g. calving.registered.v1.
  string type = 1;
  string description = 2;
  // True when a newer version replaces it; it is still delivered to the subscriptions that chose it.
  bool deprecated = 3;
}

message Capability {
  string name = 1;
  string description = 2;
  // As req 1002 and 1006 give it. access derives from it what a delegation, a join link and a service account may
  // hold, and which actions ask for a fresh sign-in; it refuses a catalog with an unspecified risk.
  CapabilityRisk risk = 3;
}

enum CapabilityRisk {
  CAPABILITY_RISK_UNSPECIFIED = 0;
  // Only reads.
  CAPABILITY_RISK_READ = 1;
  // Changes the data of an Organization or of the platform.
  CAPABILITY_RISK_WRITE = 2;
  // Changes who can act, where data goes or whether something exists: never delegated, never through a join link,
  // never held by a service account.
  CAPABILITY_RISK_ADMIN = 3;
}

message Feature {
  string name = 1;
  string description = 2;
  // Whether FeatureUsage is kept for it (req 69).
  bool metered = 3;
  // The keys an entitlement's limits may set, e.g. tokens_per_month.
  repeated string limit_keys = 4;
}

message Tool {
  // Namespaced like a capability: <system>.<tool>, e.g. farm.animals.search.
  string name = 1;
  string description = 2;
  // The MCP server and tool name that implement it.
  string mcp_server = 3;
  ToolRisk risk = 4;
  DataClass data_class = 5;
  repeated string required_capabilities = 6;
  repeated string required_features = 7;
  string version = 8;
}

enum ToolRisk {
  TOOL_RISK_UNSPECIFIED = 0;
  TOOL_RISK_READ = 1;
  TOOL_RISK_WRITE = 2;
  TOOL_RISK_DANGEROUS = 3;
}

enum DataClass {
  DATA_CLASS_UNSPECIFIED = 0;
  DATA_CLASS_PUBLIC = 1;
  DATA_CLASS_PERSONAL = 2;
}
