syntax = "proto3";

package kodex.projects.v1;

import "kodex/runtime/v1/runtime_manager.proto";

option go_package = "github.com/codex-k8s/kodex/proto/gen/go/kodex/projects/v1;projectsv1";

// ProjectCatalogService is the stable v1 inter-service contract for the
// projects and repositories domain. It covers the command and read surface
// agreed in docs/domains/projects-and-repositories/architecture/api_contract.md.
service ProjectCatalogService {
  // CreateProject creates a project in an organization.
  rpc CreateProject(CreateProjectRequest) returns (ProjectResponse);
  // UpdateProject changes safe project fields and lifecycle status.
  rpc UpdateProject(UpdateProjectRequest) returns (ProjectResponse);
  // GetProject returns authoritative project state.
  rpc GetProject(GetProjectRequest) returns (ProjectResponse);
  // ListProjects returns projects visible in an organization or filter scope.
  rpc ListProjects(ListProjectsRequest) returns (ListProjectsResponse);
  // AttachRepository binds a provider repository to a project.
  rpc AttachRepository(AttachRepositoryRequest) returns (RepositoryResponse);
  // CreateProviderRepository asks provider-hub to create a provider repository and records a project binding.
  rpc CreateProviderRepository(CreateProviderRepositoryRequest) returns (RepositoryProviderCreateResponse);
  // CreateRepositoryBootstrapPullRequest asks provider-hub to open or update a bootstrap PR for an existing binding.
  rpc CreateRepositoryBootstrapPullRequest(CreateRepositoryBootstrapPullRequestRequest) returns (RepositoryBootstrapPullRequestResponse);
  // UpdateRepository changes safe repository binding fields.
  rpc UpdateRepository(UpdateRepositoryRequest) returns (RepositoryResponse);
  // DetachRepository archives a repository binding and removes it from active project policy.
  rpc DetachRepository(DetachRepositoryRequest) returns (RepositoryResponse);
  // GetRepository returns authoritative repository binding state.
  rpc GetRepository(GetRepositoryRequest) returns (RepositoryResponse);
  // ListRepositories returns repository bindings for a project.
  rpc ListRepositories(ListRepositoriesRequest) returns (ListRepositoriesResponse);
  // ImportServicesPolicy stores a checked services.yaml projection.
  rpc ImportServicesPolicy(ImportServicesPolicyRequest) returns (ServicesPolicyResponse);
  // ImportBootstrapServicesPolicy imports checked services.yaml after a merged bootstrap PR and activates the repository binding.
  rpc ImportBootstrapServicesPolicy(ImportBootstrapServicesPolicyRequest) returns (BootstrapServicesPolicyImportResponse);
  // ReconcileBootstrapMergeSignal imports checked services.yaml from a safe provider bootstrap merge signal.
  rpc ReconcileBootstrapMergeSignal(ReconcileBootstrapMergeSignalRequest) returns (BootstrapServicesPolicyImportResponse);
  // ReconcileAdoptionMergeSignal imports checked services.yaml from a safe provider adoption merge signal.
  rpc ReconcileAdoptionMergeSignal(ReconcileAdoptionMergeSignalRequest) returns (BootstrapServicesPolicyImportResponse);
  // GetSelfDeploySignal возвращает project-side enrichment для safe provider repository change signal.
  rpc GetSelfDeploySignal(GetSelfDeploySignalRequest) returns (SelfDeploySignalResponse);
  // GetSelfDeployBuildPlan возвращает проверенный project-side build input для self-deploy runtime jobs.
  rpc GetSelfDeployBuildPlan(GetSelfDeployBuildPlanRequest) returns (SelfDeployBuildPlanResponse);
  // GetSelfDeployDeployPlan возвращает проверенный project-side deploy input после успешных build jobs.
  rpc GetSelfDeployDeployPlan(GetSelfDeployDeployPlanRequest) returns (SelfDeployDeployPlanResponse);
  // GetServicesPolicy returns a checked services.yaml projection.
  rpc GetServicesPolicy(GetServicesPolicyRequest) returns (ServicesPolicyResponse);
  // ListServiceDescriptors returns typed service descriptors from active policy.
  rpc ListServiceDescriptors(ListServiceDescriptorsRequest) returns (ListServiceDescriptorsResponse);
  // CreatePolicyEditProposal creates a request to change services.yaml through PR.
  rpc CreatePolicyEditProposal(CreatePolicyEditProposalRequest) returns (PolicyEditProposalResponse);
  // CreatePolicyOverride creates a time-bound operator override.
  rpc CreatePolicyOverride(CreatePolicyOverrideRequest) returns (PolicyOverrideResponse);
  // CancelPolicyOverride cancels an active operator override before expiration.
  rpc CancelPolicyOverride(CancelPolicyOverrideRequest) returns (PolicyOverrideResponse);
  // ListPolicyOverrides returns visible operator overrides for a project.
  rpc ListPolicyOverrides(ListPolicyOverridesRequest) returns (ListPolicyOverridesResponse);
  // PutDocumentationSource creates or updates a documentation source.
  rpc PutDocumentationSource(PutDocumentationSourceRequest) returns (DocumentationSourceResponse);
  // GetDocumentationSource returns a documentation source.
  rpc GetDocumentationSource(GetDocumentationSourceRequest) returns (DocumentationSourceResponse);
  // ListDocumentationSources returns documentation sources for a project scope.
  rpc ListDocumentationSources(ListDocumentationSourcesRequest) returns (ListDocumentationSourcesResponse);
  // GetWorkspacePolicy returns source checkout policy for an agent workspace.
  rpc GetWorkspacePolicy(GetWorkspacePolicyRequest) returns (WorkspacePolicyResponse);
  // PutBranchRules creates or updates branch rules.
  rpc PutBranchRules(PutBranchRulesRequest) returns (BranchRulesResponse);
  // GetBranchRules returns branch rules.
  rpc GetBranchRules(GetBranchRulesRequest) returns (BranchRulesResponse);
  // ListBranchRules returns active branch rules for a project or repository.
  rpc ListBranchRules(ListBranchRulesRequest) returns (ListBranchRulesResponse);
  // PutReleasePolicy creates or updates a release policy.
  rpc PutReleasePolicy(PutReleasePolicyRequest) returns (ReleasePolicyResponse);
  // GetReleasePolicy returns a release policy.
  rpc GetReleasePolicy(GetReleasePolicyRequest) returns (ReleasePolicyResponse);
  // ListReleasePolicies returns release policies for a project.
  rpc ListReleasePolicies(ListReleasePoliciesRequest) returns (ListReleasePoliciesResponse);
  // PutReleaseLine creates or updates a concrete release line.
  rpc PutReleaseLine(PutReleaseLineRequest) returns (ReleaseLineResponse);
  // GetReleaseLine returns a concrete release line.
  rpc GetReleaseLine(GetReleaseLineRequest) returns (ReleaseLineResponse);
  // ListReleaseLines returns release lines for a project or release policy.
  rpc ListReleaseLines(ListReleaseLinesRequest) returns (ListReleaseLinesResponse);
  // PutPlacementPolicy creates or updates placement policy.
  rpc PutPlacementPolicy(PutPlacementPolicyRequest) returns (PlacementPolicyResponse);
  // GetPlacementPolicy returns placement policy.
  rpc GetPlacementPolicy(GetPlacementPolicyRequest) returns (PlacementPolicyResponse);
  // ListPlacementPolicies returns placement policies for a project scope.
  rpc ListPlacementPolicies(ListPlacementPoliciesRequest) returns (ListPlacementPoliciesResponse);
}

// CommandMeta is required for every mutating command.
message CommandMeta {
  // command_id is a unique command identifier. Either command_id or idempotency_key is required.
  optional string command_id = 1;
  // idempotency_key is an idempotency key scoped by operation and actor.
  optional string idempotency_key = 2;
  // expected_version is present only for existing aggregate mutations.
  optional int64 expected_version = 3;
  // actor is the authenticated caller.
  Actor actor = 4;
  // reason is a machine or operator reason for audit and domain events.
  string reason = 5;
  // request_id links the command to logs, traces and audit.
  string request_id = 6;
  // request_context carries safe request metadata; no tokens, secrets, email or names.
  RequestContext request_context = 7;
}

// QueryMeta carries safe metadata for authoritative reads.
message QueryMeta {
  // actor is the authenticated caller.
  Actor actor = 1;
  // request_id links the read to logs and traces.
  string request_id = 2;
  // request_context carries safe request metadata.
  RequestContext request_context = 3;
}

// RequestContext is safe request metadata used for audit and diagnostics.
message RequestContext {
  // source identifies caller surface, for example staff-gateway, platform-mcp-server or service.
  string source = 1;
  // trace_id links platform traces.
  optional string trace_id = 2;
  // session_id links a user session when available.
  optional string session_id = 3;
  // client_ip_hash is an optional hashed client address.
  optional string client_ip_hash = 4;
}

// Actor identifies a user, service, agent or external account.
message Actor {
  // type is a subject type such as user, service, agent or external_account.
  string type = 1;
  // id is the subject identifier in its owner domain.
  string id = 2;
}

// PageRequest limits list responses.
message PageRequest {
  // page_size is the maximum item count requested by caller.
  int32 page_size = 1;
  // page_token is an opaque continuation token returned by a previous call.
  optional string page_token = 2;
}

// PageResponse describes list continuation state.
message PageResponse {
  // next_page_token is empty when there are no more items.
  optional string next_page_token = 1;
}

// ProjectStatus is the closed set of project lifecycle statuses.
enum ProjectStatus {
  PROJECT_STATUS_UNSPECIFIED = 0;
  PROJECT_STATUS_ACTIVE = 1;
  PROJECT_STATUS_ARCHIVED = 2;
  PROJECT_STATUS_DISABLED = 3;
}

// RepositoryProvider is the closed set of repository providers.
enum RepositoryProvider {
  REPOSITORY_PROVIDER_UNSPECIFIED = 0;
  REPOSITORY_PROVIDER_GITHUB = 1;
  REPOSITORY_PROVIDER_GITLAB = 2;
}

// RepositoryStatus is the closed set of repository binding statuses.
enum RepositoryStatus {
  REPOSITORY_STATUS_UNSPECIFIED = 0;
  REPOSITORY_STATUS_ACTIVE = 1;
  REPOSITORY_STATUS_PENDING = 2;
  REPOSITORY_STATUS_BLOCKED = 3;
  REPOSITORY_STATUS_ARCHIVED = 4;
}

// RepositoryOwnerKind selects provider-side repository owner semantics.
enum RepositoryOwnerKind {
  REPOSITORY_OWNER_KIND_UNSPECIFIED = 0;
  REPOSITORY_OWNER_KIND_ORGANIZATION = 1;
  REPOSITORY_OWNER_KIND_AUTHENTICATED_USER = 2;
}

// RepositoryVisibility selects provider-side repository visibility.
enum RepositoryVisibility {
  REPOSITORY_VISIBILITY_UNSPECIFIED = 0;
  REPOSITORY_VISIBILITY_PUBLIC = 1;
  REPOSITORY_VISIBILITY_PRIVATE = 2;
  REPOSITORY_VISIBILITY_INTERNAL = 3;
}

// ServicesPolicyValidationStatus is the validation state of imported services.yaml.
enum ServicesPolicyValidationStatus {
  SERVICES_POLICY_VALIDATION_STATUS_UNSPECIFIED = 0;
  SERVICES_POLICY_VALIDATION_STATUS_VALID = 1;
  SERVICES_POLICY_VALIDATION_STATUS_INVALID = 2;
  SERVICES_POLICY_VALIDATION_STATUS_STALE = 3;
}

// ServicesPolicyProjectionStatus is the projection state of imported services.yaml.
enum ServicesPolicyProjectionStatus {
  SERVICES_POLICY_PROJECTION_STATUS_UNSPECIFIED = 0;
  SERVICES_POLICY_PROJECTION_STATUS_SYNCED = 1;
  SERVICES_POLICY_PROJECTION_STATUS_PENDING = 2;
  SERVICES_POLICY_PROJECTION_STATUS_FAILED = 3;
  SERVICES_POLICY_PROJECTION_STATUS_OVERRIDDEN = 4;
}

// SelfDeploySignalStatus описывает готовность project-side self-deploy input.
enum SelfDeploySignalStatus {
  SELF_DEPLOY_SIGNAL_STATUS_UNSPECIFIED = 0;
  SELF_DEPLOY_SIGNAL_STATUS_READY = 1;
  SELF_DEPLOY_SIGNAL_STATUS_NEEDS_SERVICES_POLICY_RECONCILE = 2;
  SELF_DEPLOY_SIGNAL_STATUS_PROVIDER_SIGNAL_NOT_FOUND = 3;
  SELF_DEPLOY_SIGNAL_STATUS_PROVIDER_SIGNAL_NOT_READY = 4;
  SELF_DEPLOY_SIGNAL_STATUS_REPOSITORY_BINDING_NOT_FOUND = 5;
  SELF_DEPLOY_SIGNAL_STATUS_SERVICES_POLICY_NOT_FOUND = 6;
  SELF_DEPLOY_SIGNAL_STATUS_SERVICES_POLICY_NOT_READY = 7;
  SELF_DEPLOY_SIGNAL_STATUS_NOT_DEPLOY_RELEVANT = 8;
  SELF_DEPLOY_SIGNAL_STATUS_NEEDS_REPOSITORY_CHANGE_SUMMARY = 9;
}

// SelfDeployBuildPlanStatus описывает готовность проверенного build plan для runtime-manager JOB_TYPE_BUILD.
enum SelfDeployBuildPlanStatus {
  SELF_DEPLOY_BUILD_PLAN_STATUS_UNSPECIFIED = 0;
  SELF_DEPLOY_BUILD_PLAN_STATUS_READY = 1;
  SELF_DEPLOY_BUILD_PLAN_STATUS_BUILD_PLAN_UNAVAILABLE = 2;
  SELF_DEPLOY_BUILD_PLAN_STATUS_POLICY_STALE = 3;
  SELF_DEPLOY_BUILD_PLAN_STATUS_SERVICE_NOT_FOUND = 4;
  SELF_DEPLOY_BUILD_PLAN_STATUS_INVALID_INPUT = 5;
  SELF_DEPLOY_BUILD_PLAN_STATUS_BUILD_CONTEXT_UNAVAILABLE = 6;
  SELF_DEPLOY_BUILD_PLAN_STATUS_BUILD_CONTEXT_REQUIRED = 7;
  SELF_DEPLOY_BUILD_PLAN_STATUS_BUILD_CONTEXT_INVALID = 8;
}

// SelfDeployBuildPlanItemStatus описывает готовность build item одного сервиса.
enum SelfDeployBuildPlanItemStatus {
  SELF_DEPLOY_BUILD_PLAN_ITEM_STATUS_UNSPECIFIED = 0;
  SELF_DEPLOY_BUILD_PLAN_ITEM_STATUS_READY = 1;
  SELF_DEPLOY_BUILD_PLAN_ITEM_STATUS_BUILD_CONTEXT_REQUIRED = 2;
  SELF_DEPLOY_BUILD_PLAN_ITEM_STATUS_BUILD_CONTEXT_INVALID = 3;
  SELF_DEPLOY_BUILD_PLAN_ITEM_STATUS_BUILD_PLAN_UNAVAILABLE = 4;
}

// SelfDeployDeployPlanStatus описывает готовность checked deploy plan для runtime-manager JOB_TYPE_DEPLOY.
enum SelfDeployDeployPlanStatus {
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_UNSPECIFIED = 0;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_READY = 1;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_DEPLOY_PLAN_UNAVAILABLE = 2;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_POLICY_STALE = 3;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_SERVICE_NOT_FOUND = 4;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_INVALID_INPUT = 5;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_BUILD_NOT_READY = 6;
  SELF_DEPLOY_DEPLOY_PLAN_STATUS_BUILD_OUTPUT_INVALID = 7;
}

// SelfDeployDeployPlanItemStatus описывает готовность deploy item одного сервиса.
enum SelfDeployDeployPlanItemStatus {
  SELF_DEPLOY_DEPLOY_PLAN_ITEM_STATUS_UNSPECIFIED = 0;
  SELF_DEPLOY_DEPLOY_PLAN_ITEM_STATUS_READY = 1;
  SELF_DEPLOY_DEPLOY_PLAN_ITEM_STATUS_BUILD_NOT_READY = 2;
  SELF_DEPLOY_DEPLOY_PLAN_ITEM_STATUS_BUILD_OUTPUT_INVALID = 3;
  SELF_DEPLOY_DEPLOY_PLAN_ITEM_STATUS_DEPLOY_PLAN_UNAVAILABLE = 4;
}

// SelfDeployPathCategory классифицирует изменённые пути без raw paths и diffs.
enum SelfDeployPathCategory {
  SELF_DEPLOY_PATH_CATEGORY_UNSPECIFIED = 0;
  SELF_DEPLOY_PATH_CATEGORY_SERVICES_POLICY = 1;
  SELF_DEPLOY_PATH_CATEGORY_SERVICE_SOURCE = 2;
  SELF_DEPLOY_PATH_CATEGORY_SERVICE_CONFIG = 3;
  SELF_DEPLOY_PATH_CATEGORY_DEPLOY_MANIFEST = 4;
  SELF_DEPLOY_PATH_CATEGORY_RUNTIME_CONFIG = 5;
  SELF_DEPLOY_PATH_CATEGORY_DOCUMENTATION = 6;
  SELF_DEPLOY_PATH_CATEGORY_TEST = 7;
  SELF_DEPLOY_PATH_CATEGORY_PLATFORM_POLICY = 8;
  SELF_DEPLOY_PATH_CATEGORY_OTHER = 9;
}

// SelfDeployExpectedRuntimeJobType задаёт project-side safe подсказку типа runtime job.
enum SelfDeployExpectedRuntimeJobType {
  SELF_DEPLOY_EXPECTED_RUNTIME_JOB_TYPE_UNSPECIFIED = 0;
  SELF_DEPLOY_EXPECTED_RUNTIME_JOB_TYPE_BUILD = 1;
  SELF_DEPLOY_EXPECTED_RUNTIME_JOB_TYPE_DEPLOY = 2;
  SELF_DEPLOY_EXPECTED_RUNTIME_JOB_TYPE_HEALTH_CHECK = 3;
}

// ServiceKind classifies a service described by services.yaml.
enum ServiceKind {
  SERVICE_KIND_UNSPECIFIED = 0;
  SERVICE_KIND_BACKEND = 1;
  SERVICE_KIND_FRONTEND = 2;
  SERVICE_KIND_WORKER = 3;
  SERVICE_KIND_DOCUMENTATION = 4;
  SERVICE_KIND_PACKAGE = 5;
  SERVICE_KIND_OTHER = 6;
}

// ServiceStatus is the closed set of service descriptor statuses.
enum ServiceStatus {
  SERVICE_STATUS_UNSPECIFIED = 0;
  SERVICE_STATUS_ACTIVE = 1;
  SERVICE_STATUS_DISABLED = 2;
  SERVICE_STATUS_STALE = 3;
}

// DocumentationScopeType classifies where documentation source applies.
enum DocumentationScopeType {
  DOCUMENTATION_SCOPE_TYPE_UNSPECIFIED = 0;
  DOCUMENTATION_SCOPE_TYPE_PROJECT = 1;
  DOCUMENTATION_SCOPE_TYPE_SERVICE = 2;
  DOCUMENTATION_SCOPE_TYPE_DEPENDENCY = 3;
  DOCUMENTATION_SCOPE_TYPE_GUIDANCE_REF = 4;
}

// DocumentationAccessMode controls whether an agent may edit a documentation source.
enum DocumentationAccessMode {
  DOCUMENTATION_ACCESS_MODE_UNSPECIFIED = 0;
  DOCUMENTATION_ACCESS_MODE_READ = 1;
  DOCUMENTATION_ACCESS_MODE_WRITE = 2;
}

// SourceAccessMode controls whether a workspace source is editable.
enum SourceAccessMode {
  SOURCE_ACCESS_MODE_UNSPECIFIED = 0;
  SOURCE_ACCESS_MODE_READ = 1;
  SOURCE_ACCESS_MODE_WRITE = 2;
}

// DocumentationSourceStatus is the closed set of documentation source statuses.
enum DocumentationSourceStatus {
  DOCUMENTATION_SOURCE_STATUS_UNSPECIFIED = 0;
  DOCUMENTATION_SOURCE_STATUS_ACTIVE = 1;
  DOCUMENTATION_SOURCE_STATUS_DISABLED = 2;
  DOCUMENTATION_SOURCE_STATUS_BLOCKED = 3;
}

// MergePolicy is the closed set of merge strategies allowed by branch rules.
enum MergePolicy {
  MERGE_POLICY_UNSPECIFIED = 0;
  MERGE_POLICY_MERGE = 1;
  MERGE_POLICY_SQUASH = 2;
  MERGE_POLICY_REBASE = 3;
  MERGE_POLICY_MANUAL = 4;
}

// BranchRulesStatus is the closed set of branch rule statuses.
enum BranchRulesStatus {
  BRANCH_RULES_STATUS_UNSPECIFIED = 0;
  BRANCH_RULES_STATUS_ACTIVE = 1;
  BRANCH_RULES_STATUS_DISABLED = 2;
}

// RolloutStrategy is the closed set of release rollout strategies.
enum RolloutStrategy {
  ROLLOUT_STRATEGY_UNSPECIFIED = 0;
  ROLLOUT_STRATEGY_DIRECT = 1;
  ROLLOUT_STRATEGY_STAGED = 2;
  ROLLOUT_STRATEGY_CANARY = 3;
}

// RollbackPolicy is the closed set of release rollback policies.
enum RollbackPolicy {
  ROLLBACK_POLICY_UNSPECIFIED = 0;
  ROLLBACK_POLICY_MANUAL = 1;
  ROLLBACK_POLICY_AUTOMATIC_ON_GATE = 2;
  ROLLBACK_POLICY_AUTOMATIC_ON_ALERT = 3;
}

// ReleasePolicyStatus is the closed set of release policy statuses.
enum ReleasePolicyStatus {
  RELEASE_POLICY_STATUS_UNSPECIFIED = 0;
  RELEASE_POLICY_STATUS_ACTIVE = 1;
  RELEASE_POLICY_STATUS_DISABLED = 2;
  RELEASE_POLICY_STATUS_ARCHIVED = 3;
}

// PlacementPolicyStatus is the closed set of placement policy statuses.
enum PlacementPolicyStatus {
  PLACEMENT_POLICY_STATUS_UNSPECIFIED = 0;
  PLACEMENT_POLICY_STATUS_ACTIVE = 1;
  PLACEMENT_POLICY_STATUS_DISABLED = 2;
}

// PolicyOverrideTargetType is the closed set of override target types.
enum PolicyOverrideTargetType {
  POLICY_OVERRIDE_TARGET_TYPE_UNSPECIFIED = 0;
  POLICY_OVERRIDE_TARGET_TYPE_SERVICES_POLICY = 1;
  POLICY_OVERRIDE_TARGET_TYPE_BRANCH_RULES = 2;
  POLICY_OVERRIDE_TARGET_TYPE_RELEASE_POLICY = 3;
  POLICY_OVERRIDE_TARGET_TYPE_PLACEMENT_POLICY = 4;
  POLICY_OVERRIDE_TARGET_TYPE_DOCUMENTATION_SOURCE = 5;
  POLICY_OVERRIDE_TARGET_TYPE_RELEASE_LINE = 6;
}

// PolicyOverrideStatus is the closed set of override statuses.
enum PolicyOverrideStatus {
  POLICY_OVERRIDE_STATUS_UNSPECIFIED = 0;
  POLICY_OVERRIDE_STATUS_ACTIVE = 1;
  POLICY_OVERRIDE_STATUS_EXPIRED = 2;
  POLICY_OVERRIDE_STATUS_CANCELLED = 3;
}

// Project describes a project aggregate.
message Project {
  // project_id is the project aggregate id.
  string project_id = 1;
  // organization_id is the owner organization id from access-manager.
  string organization_id = 2;
  // slug is unique in organization scope.
  string slug = 3;
  // display_name is safe display text.
  string display_name = 4;
  // description is optional safe description.
  optional string description = 5;
  // icon_object_uri is an optional object-store URI for project icon.
  optional string icon_object_uri = 6;
  // status is project lifecycle status.
  ProjectStatus status = 7;
  // version is the aggregate version.
  int64 version = 8;
}

// Repository describes a repository binding aggregate.
message Repository {
  // repository_id is the repository binding aggregate id.
  string repository_id = 1;
  // project_id is the project that owns the binding.
  string project_id = 2;
  // provider is the repository provider.
  RepositoryProvider provider = 3;
  // provider_owner is owner or group name at provider.
  string provider_owner = 4;
  // provider_name is repository name at provider.
  string provider_name = 5;
  // web_url is a safe URL to the provider repository.
  string web_url = 6;
  // default_branch is the default branch for project policy.
  string default_branch = 7;
  // status is repository binding status.
  RepositoryStatus status = 8;
  // provider_repository_id is optional provider-native id.
  optional string provider_repository_id = 9;
  // icon_object_uri is an optional object-store URI for repository icon.
  optional string icon_object_uri = 10;
  // version is the aggregate version.
  int64 version = 11;
}

// RepositoryBootstrapFile is one prepared text file for an empty-repository bootstrap branch.
message RepositoryBootstrapFile {
  // path is a repository-relative file path.
  string path = 1;
  // content is UTF-8 text prepared outside project-catalog.
  string content = 2;
  // executable marks files that should be executable when the provider supports it.
  bool executable = 3;
}

// RepositoryBootstrapServicesPolicy links prepared bootstrap files to a checked services.yaml projection.
message RepositoryBootstrapServicesPolicy {
  // source_path is the repository-relative path of services.yaml inside prepared files.
  string source_path = 1;
  // content_hash is the checked source content hash accepted by project policy.
  string content_hash = 2;
  // validated_payload_json is normalized services.yaml payload accepted by project policy.
  string validated_payload_json = 3;
}

// RepositoryBootstrapProviderTarget is the provider repository target derived from project binding.
message RepositoryBootstrapProviderTarget {
  // provider_slug is the extensible provider identifier passed to provider-hub.
  string provider_slug = 1;
  // repository_full_name is owner/name or provider equivalent.
  string repository_full_name = 2;
  // provider_repository_id is the provider-native repository id when known.
  optional string provider_repository_id = 3;
  // web_url is the safe provider repository URL from the binding.
  optional string web_url = 4;
}

// ServicesPolicy describes a checked services.yaml projection.
message ServicesPolicy {
  // services_policy_id is the policy aggregate id.
  string services_policy_id = 1;
  // project_id is the project that owns the policy.
  string project_id = 2;
  // source_repository_id is the repository where source services.yaml was found.
  optional string source_repository_id = 3;
  // source_path is the policy file path.
  string source_path = 4;
  // source_ref is the branch, tag or provider ref used for import.
  optional string source_ref = 5;
  // source_commit_sha is the commit used for checked projection.
  string source_commit_sha = 6;
  // source_blob_sha is the provider file object hash when available.
  optional string source_blob_sha = 7;
  // policy_version is the checked policy version.
  int64 policy_version = 8;
  // content_hash is the normalized source content hash.
  string content_hash = 9;
  // validated_payload_json is normalized payload for audit and revalidation.
  string validated_payload_json = 10;
  // validation_status is source validation status.
  ServicesPolicyValidationStatus validation_status = 11;
  // projection_status is operational projection status.
  ServicesPolicyProjectionStatus projection_status = 12;
  // imported_at is the import time in RFC3339 format.
  string imported_at = 13;
}

// ServiceDescriptor describes one typed service from checked services.yaml.
message ServiceDescriptor {
  // service_descriptor_id is the service descriptor id.
  string service_descriptor_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // services_policy_id is the source checked policy id.
  string services_policy_id = 3;
  // repository_id is optional repository binding id.
  optional string repository_id = 4;
  // service_key is stable service key from services.yaml.
  string service_key = 5;
  // display_name is safe display text.
  string display_name = 6;
  // kind classifies the service.
  ServiceKind kind = 7;
  // root_path is the service root in workspace.
  string root_path = 8;
  // documentation_scope_id links service to documentation sources.
  optional string documentation_scope_id = 9;
  // depends_on_service_keys lists project service dependencies.
  repeated string depends_on_service_keys = 10;
  // status is service descriptor status.
  ServiceStatus status = 11;
  // version is the descriptor version.
  int64 version = 12;
}

// SelfDeployPathCategoryCount содержит safe счётчики категорий путей без raw paths.
message SelfDeployPathCategoryCount {
  // category классифицирует семейство изменённых путей.
  SelfDeployPathCategory category = 1;
  // count — bounded provider-side счётчик для категории.
  int64 count = 2;
}

// SelfDeployGovernanceRequirement содержит только safe governance hints.
message SelfDeployGovernanceRequirement {
  // gate_required сообщает agent-manager, что до runtime jobs нужен owner/governance approval.
  bool gate_required = 1;
  // risk_profile_ref опционально указывает на governance policy без копирования решений.
  optional string risk_profile_ref = 2;
  // gate_policy_ref опционально указывает на gate policy для оценки.
  optional string gate_policy_ref = 3;
}

// SelfDeployServicesYamlProjection описывает checked project-owned проекцию services.yaml.
message SelfDeployServicesYamlProjection {
  // services_yaml_ref — safe project-catalog ссылка на checked projection.
  string services_yaml_ref = 1;
  // services_yaml_digest — checked normalized services.yaml digest, а не provider path_digest.
  string services_yaml_digest = 2;
  // services_yaml_fingerprint — стабильный safe fingerprint checked projection.
  string services_yaml_fingerprint = 3;
  // services_policy_id — aggregate id в project-catalog.
  string services_policy_id = 4;
  // source_repository_id — repository binding источника projection.
  optional string source_repository_id = 5;
  // source_path — путь checked services.yaml.
  string source_path = 6;
  // source_ref — branch, tag или provider ref, использованный для import.
  optional string source_ref = 7;
  // source_commit_sha — commit checked projection.
  string source_commit_sha = 8;
  // policy_version — версия checked projection.
  int64 policy_version = 9;
  // validation_status — статус проверки source.
  ServicesPolicyValidationStatus validation_status = 10;
  // projection_status — операционный статус projection.
  ServicesPolicyProjectionStatus projection_status = 11;
  // imported_at — время import в формате RFC3339.
  string imported_at = 12;
}

// SelfDeploySignal — project-side safe input для agent-manager SelfDeployPlan.
message SelfDeploySignal {
  // provider_signal_ref — стабильный provider signal idempotency ref.
  string provider_signal_ref = 1;
  // provider_signal_id — persisted signal id в provider-hub, если известен.
  optional string provider_signal_id = 2;
  // provider_signal_key — idempotency key в provider-hub, если известен.
  optional string provider_signal_key = 3;
  // project_ref — project ref в project-catalog.
  string project_ref = 4;
  // repository_ref — repository binding ref в project-catalog.
  string repository_ref = 5;
  // provider_slug идентифицирует provider adapter.
  string provider_slug = 6;
  // repository_full_name — safe provider owner/name.
  string repository_full_name = 7;
  // provider_repository_id — provider-native repository id, если известен.
  optional string provider_repository_id = 8;
  // source_ref — provider ref, который изменился.
  string source_ref = 9;
  // merge_commit_sha — observed head или merge commit sha.
  string merge_commit_sha = 10;
  // services_yaml присутствует, когда у project-catalog есть checked projection.
  SelfDeployServicesYamlProjection services_yaml = 11;
  // affected_service_keys вычисляются только из checked ServicesPolicy descriptors.
  repeated string affected_service_keys = 12;
  // path_categories — safe provider categories, переложенные в project vocabulary.
  repeated SelfDeployPathCategoryCount path_categories = 13;
  // services_yaml_changed показывает, видел ли provider-hub изменение root services.yaml.
  bool services_yaml_changed = 14;
  // deploy_relevant_changed показывает, видел ли provider-hub deploy-relevant categories.
  bool deploy_relevant_changed = 15;
  // expected_runtime_job_types — safe job type hints для agent-manager.
  repeated SelfDeployExpectedRuntimeJobType expected_runtime_job_types = 16;
  // governance_requirement показывает, нужен ли owner/governance gate.
  SelfDeployGovernanceRequirement governance_requirement = 17;
  // provider_change_fingerprint — provider-owned signal fingerprint.
  string provider_change_fingerprint = 18;
  // project_signal_fingerprint — project-side enrichment fingerprint.
  string project_signal_fingerprint = 19;
  // provider_etag — provider-hub safe read token, если известен.
  optional string provider_etag = 20;
  // safe_summary — bounded diagnostic text без raw payloads.
  string safe_summary = 21;
  // observed_at — время provider observation в формате RFC3339.
  string observed_at = 22;
  // version — версия project-side signal contract.
  int64 version = 23;
}

// SelfDeployBuildRecipe содержит статический проверенный рецепт сборки из ServicesPolicy.
message SelfDeployBuildRecipe {
  // image_ref — целевой image repository/ref без digest.
  string image_ref = 1;
  // image_tag — checked tag policy для build результата.
  string image_tag = 2;
  // image_digest заполняется только если checked policy уже содержит безопасный digest.
  optional string image_digest = 3;
  // dockerfile_ref — путь Dockerfile внутри будущего build context.
  string dockerfile_ref = 4;
  // dockerfile_target — фиксированный Dockerfile target.
  string dockerfile_target = 5;
  // builder_image_ref — approved builder image.
  string builder_image_ref = 6;
  // allowed_secret_refs — refs секретов без значений.
  repeated kodex.runtime.v1.RuntimeJobAllowedSecretRef allowed_secret_refs = 7;
  // output_refs — refs ожидаемых build outputs.
  repeated kodex.runtime.v1.RuntimeJobOutputRef output_refs = 8;
  // recipe_fingerprint — стабильный fingerprint рецепта без runtime context.
  string recipe_fingerprint = 9;
}

// SelfDeployMaterializedBuildContext содержит build context, подготовленный runtime-manager.
message SelfDeployMaterializedBuildContext {
  // service_key связывает context с affected service key.
  string service_key = 1;
  // plan_item_fingerprint опционально связывает context с ранее выданным item рецепта.
  optional string plan_item_fingerprint = 2;
  // build_context_ref — ref подготовленного context.
  string build_context_ref = 3;
  // build_context_digest — digest подготовленного context.
  string build_context_digest = 4;
  // dockerfile_digest — digest Dockerfile внутри context, если runtime его посчитал.
  optional string dockerfile_digest = 5;
  // materialization_ref — safe ref runtime materialization attempt.
  optional string materialization_ref = 6;
  // materialization_fingerprint — safe fingerprint runtime materialization result.
  optional string materialization_fingerprint = 7;
  // manifest_bundle_digest — actual YAML bundle digest prepared by runtime-manager.
  optional string manifest_bundle_digest = 8;
}

// SelfDeployBuildPlanItem содержит рецепт и, когда context готов, runtime build spec для одного сервиса.
message SelfDeployBuildPlanItem {
  // service_key идентифицирует service descriptor из checked ServicesPolicy.
  string service_key = 1;
  // service_ref — safe ref service descriptor в project-catalog.
  string service_ref = 2;
  // build_execution_spec совместим с runtime-manager JOB_TYPE_BUILD и присутствует только для ready item.
  kodex.runtime.v1.BuildExecutionSpec build_execution_spec = 3;
  // plan_item_fingerprint — стабильный fingerprint item без raw YAML.
  string plan_item_fingerprint = 4;
  // status описывает готовность item.
  SelfDeployBuildPlanItemStatus status = 5;
  // build_recipe содержит статический проверенный рецепт без runtime context.
  SelfDeployBuildRecipe build_recipe = 6;
  // safe_reason объясняет non-ready item без raw payloads и секретов.
  optional string safe_reason = 7;
}

// SelfDeployBuildPlan — проверенный project-owned plan для подготовки build jobs.
message SelfDeployBuildPlan {
  // project_ref — project ref в project-catalog.
  string project_ref = 1;
  // repository_ref — repository binding ref в project-catalog.
  string repository_ref = 2;
  // provider_signal_ref — safe provider/project signal ref, если известен.
  optional string provider_signal_ref = 3;
  // source_ref — provider/source ref, который послужил trigger.
  string source_ref = 4;
  // merge_commit_sha — commit source snapshot.
  string merge_commit_sha = 5;
  // services_yaml — checked project-owned policy projection.
  SelfDeployServicesYamlProjection services_yaml = 6;
  // affected_service_keys — нормализованный список запрошенных сервисов.
  repeated string affected_service_keys = 7;
  // build_items — per-service typed build specs.
  repeated SelfDeployBuildPlanItem build_items = 8;
  // plan_fingerprint — стабильный fingerprint всего checked build plan.
  string plan_fingerprint = 9;
  // safe_summary — bounded diagnostic summary без raw payloads.
  string safe_summary = 10;
  // version — версия build plan contract.
  int64 version = 11;
}

// SelfDeployBuildOutput содержит safe результат успешной build job для deploy planning.
message SelfDeployBuildOutput {
  string service_key = 1;
  optional string runtime_job_ref = 2;
  string image_ref = 3;
  string image_tag = 4;
  optional string image_digest = 5;
  optional string build_plan_item_fingerprint = 6;
  optional string build_plan_fingerprint = 7;
  optional string build_context_ref = 8;
  optional string build_context_digest = 9;
}

// SelfDeployDeployPlanItem содержит checked deploy spec одного сервиса.
message SelfDeployDeployPlanItem {
  string service_key = 1;
  optional string service_ref = 2;
  kodex.runtime.v1.DeployExecutionSpec deploy_execution_spec = 3;
  string plan_item_fingerprint = 4;
  SelfDeployDeployPlanItemStatus status = 5;
  optional string safe_reason = 6;
}

// SelfDeployDeployPlan содержит checked project-owned deploy inputs.
message SelfDeployDeployPlan {
  string project_ref = 1;
  string repository_ref = 2;
  optional string provider_signal_ref = 3;
  string source_ref = 4;
  string merge_commit_sha = 5;
  SelfDeployServicesYamlProjection services_yaml = 6;
  repeated string affected_service_keys = 7;
  repeated SelfDeployDeployPlanItem deploy_items = 8;
  string plan_fingerprint = 9;
  string safe_summary = 10;
  int64 version = 11;
}

// DocumentationSource describes one project documentation source.
message DocumentationSource {
  // documentation_source_id is the source aggregate id.
  string documentation_source_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id is optional repository binding id.
  optional string repository_id = 3;
  // scope_type classifies where the source applies.
  DocumentationScopeType scope_type = 4;
  // scope_id is optional service, dependency or guidance scope id.
  optional string scope_id = 5;
  // local_path is target path in workspace.
  string local_path = 6;
  // access_mode controls whether the source is editable.
  DocumentationAccessMode access_mode = 7;
  // status is source status.
  DocumentationSourceStatus status = 8;
  // version is the aggregate version.
  int64 version = 9;
}

// BranchRules describes branch policy.
message BranchRules {
  // branch_rules_id is the branch rule aggregate id.
  string branch_rules_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id narrows rules to one repository when set.
  optional string repository_id = 3;
  // pattern is the branch name pattern.
  string pattern = 4;
  // required_checks are provider check names required by policy.
  repeated string required_checks = 5;
  // merge_policy is the allowed merge strategy.
  MergePolicy merge_policy = 6;
  // status is branch rules status.
  BranchRulesStatus status = 7;
  // version is the aggregate version.
  int64 version = 8;
}

// ReleasePolicy describes release policy.
message ReleasePolicy {
  // release_policy_id is the release policy aggregate id.
  string release_policy_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // name is the policy display name.
  string name = 3;
  // branch_pattern is release branch pattern.
  string branch_pattern = 4;
  // rollout_strategy is the deployment rollout strategy.
  RolloutStrategy rollout_strategy = 5;
  // rollback_policy is the rollback rule.
  RollbackPolicy rollback_policy = 6;
  // risk_profile_ref references governance risk profile.
  optional string risk_profile_ref = 7;
  // status is release policy status.
  ReleasePolicyStatus status = 8;
  // version is the aggregate version.
  int64 version = 9;
}

// ReleaseLine describes a concrete release line.
message ReleaseLine {
  // release_line_id is the release line aggregate id.
  string release_line_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // release_policy_id is the source release policy id.
  string release_policy_id = 3;
  // name is the release line name.
  string name = 4;
  // branch_pattern is release branch pattern.
  string branch_pattern = 5;
  // status is release line status.
  ReleasePolicyStatus status = 6;
  // version is the aggregate version.
  int64 version = 7;
}

// PlacementPolicy describes allowed runtime placement.
message PlacementPolicy {
  // placement_policy_id is the placement policy aggregate id.
  string placement_policy_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id narrows policy to one repository when set.
  optional string repository_id = 3;
  // service_key narrows policy to one service when set.
  optional string service_key = 4;
  // allowed_cluster_refs contains fleet-manager cluster references.
  repeated string allowed_cluster_refs = 5;
  // status is placement policy status.
  PlacementPolicyStatus status = 6;
  // version is the aggregate version.
  int64 version = 7;
}

// PolicyOverride describes a time-bound operator override.
message PolicyOverride {
  // policy_override_id is the override aggregate id.
  string policy_override_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // target_type classifies overridden policy area.
  PolicyOverrideTargetType target_type = 3;
  // target_id is optional concrete aggregate id.
  optional string target_id = 4;
  // payload_json is the minimum override payload.
  string payload_json = 5;
  // reason is the operator reason.
  string reason = 6;
  // status is override lifecycle status.
  PolicyOverrideStatus status = 7;
  // expires_at is the expiration timestamp in RFC3339 format.
  string expires_at = 8;
  // created_by_actor_ref references the operator for audit.
  string created_by_actor_ref = 9;
  // version is the aggregate version.
  int64 version = 10;
}

// WorkspacePolicy describes sources allowed in an agent workspace.
message WorkspacePolicy {
  // project_id is the project id.
  string project_id = 1;
  // code_sources are code repositories allowed in workspace.
  repeated WorkspaceCodeSource code_sources = 2;
  // documentation_sources are documentation sources allowed in workspace.
  repeated WorkspaceDocumentationSource documentation_sources = 3;
  // guidance_package_refs are installed guidance package references.
  repeated string guidance_package_refs = 4;
  // policy_version is the services policy version used to build this result.
  int64 policy_version = 5;
  // active_policy_overrides are active emergency deviations from Git-managed policy.
  repeated PolicyOverride active_policy_overrides = 6;
}

// WorkspaceCodeSource describes one code checkout source.
message WorkspaceCodeSource {
  // repository_id is the repository binding id.
  string repository_id = 1;
  // provider is the repository provider.
  RepositoryProvider provider = 2;
  // provider_owner is owner or group name at provider.
  string provider_owner = 3;
  // provider_name is repository name at provider.
  string provider_name = 4;
  // default_branch is the default branch to checkout unless task overrides it.
  string default_branch = 5;
  // local_path is the target path in workspace.
  string local_path = 6;
  // access_mode controls whether the source is editable.
  SourceAccessMode access_mode = 7;
}

// WorkspaceDocumentationSource describes one documentation checkout source.
message WorkspaceDocumentationSource {
  // documentation_source_id is the documentation source id.
  string documentation_source_id = 1;
  // repository_id is optional repository binding id.
  optional string repository_id = 2;
  // scope_type classifies where the source applies.
  DocumentationScopeType scope_type = 3;
  // scope_id is optional service, dependency or guidance scope id.
  optional string scope_id = 4;
  // local_path is the target path in workspace.
  string local_path = 5;
  // access_mode controls whether the source is editable.
  SourceAccessMode access_mode = 6;
}

// CreateProjectRequest creates a project.
message CreateProjectRequest {
  // organization_id is the owner organization id.
  string organization_id = 1;
  // slug is unique project slug in organization scope.
  string slug = 2;
  // display_name is safe display text.
  string display_name = 3;
  // description is optional safe description.
  optional string description = 4;
  // icon_object_uri is an optional object-store URI for project icon.
  optional string icon_object_uri = 5;
  // status is optional target status; server defaults to active.
  optional ProjectStatus status = 6;
  // meta carries idempotency and audit context.
  CommandMeta meta = 7;
}

// UpdateProjectRequest changes safe project fields.
message UpdateProjectRequest {
  // project_id is the project aggregate id.
  string project_id = 1;
  // slug is optional new slug.
  optional string slug = 2;
  // display_name is optional safe display text.
  optional string display_name = 3;
  // description is optional safe description; present empty value clears it.
  optional string description = 4;
  // icon_object_uri is optional icon URI; present empty value clears it.
  optional string icon_object_uri = 5;
  // status is optional target lifecycle status.
  optional ProjectStatus status = 6;
  // meta carries idempotency, expected version and audit context.
  CommandMeta meta = 7;
}

// ProjectResponse returns project state.
message ProjectResponse {
  // project is the returned project state.
  Project project = 1;
}

// GetProjectRequest reads a project by id.
message GetProjectRequest {
  // project_id is the project aggregate id.
  string project_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListProjectsRequest lists projects by organization and status.
message ListProjectsRequest {
  // organization_id optionally filters projects by organization.
  optional string organization_id = 1;
  // statuses optionally filter project lifecycle.
  repeated ProjectStatus statuses = 2;
  // page limits response size.
  PageRequest page = 3;
  // meta carries read actor and request context.
  QueryMeta meta = 4;
}

// ListProjectsResponse returns project list.
message ListProjectsResponse {
  // projects are returned in stable server-defined order.
  repeated Project projects = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// AttachRepositoryRequest attaches a repository to a project.
message AttachRepositoryRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // provider is the repository provider.
  RepositoryProvider provider = 2;
  // provider_owner is owner or group name at provider.
  string provider_owner = 3;
  // provider_name is repository name at provider.
  string provider_name = 4;
  // web_url is a safe URL to the provider repository.
  string web_url = 5;
  // default_branch is the default branch.
  string default_branch = 6;
  // provider_repository_id is optional provider-native id.
  optional string provider_repository_id = 7;
  // icon_object_uri is an optional object-store URI for repository icon.
  optional string icon_object_uri = 8;
  // status is optional target status; server defaults to active.
  optional RepositoryStatus status = 9;
  // meta carries idempotency and audit context.
  CommandMeta meta = 10;
}

// UpdateRepositoryRequest changes repository binding fields.
message UpdateRepositoryRequest {
  // repository_id is the repository binding aggregate id.
  string repository_id = 1;
  // default_branch is optional new default branch.
  optional string default_branch = 2;
  // status is optional target lifecycle status.
  optional RepositoryStatus status = 3;
  // icon_object_uri is optional icon URI; present empty value clears it.
  optional string icon_object_uri = 4;
  // meta carries idempotency, expected version and audit context.
  CommandMeta meta = 5;
}

// DetachRepositoryRequest archives an active repository binding.
message DetachRepositoryRequest {
  // repository_id is the repository binding aggregate id.
  string repository_id = 1;
  // meta carries idempotency, expected version and audit context.
  CommandMeta meta = 2;
}

// RepositoryResponse returns repository binding state.
message RepositoryResponse {
  // repository is the returned repository state.
  Repository repository = 1;
}

// CreateProviderRepositoryRequest creates a provider repository through provider-hub and links it to the project.
message CreateProviderRepositoryRequest {
  // project_id owns the project repository binding.
  string project_id = 1;
  // provider is the repository provider.
  RepositoryProvider provider = 2;
  // owner_kind selects organization or authenticated-user provider create semantics.
  RepositoryOwnerKind owner_kind = 3;
  // provider_owner is the owner/group path stored in the project binding. For authenticated-user creates this is the expected account login, while provider-hub receives no explicit owner override.
  string provider_owner = 4;
  // provider_name is repository name at provider.
  string provider_name = 5;
  // visibility is the requested provider repository visibility.
  RepositoryVisibility visibility = 6;
  // description is an optional safe provider repository description.
  optional string description = 7;
  // icon_object_uri is an optional object-store URI for repository icon.
  optional string icon_object_uri = 8;
  // external_account_id is the selected provider account for provider-hub writes.
  string external_account_id = 9;
  // meta carries command identity, actor and audit context.
  CommandMeta meta = 10;
}

// RepositoryProviderCreateResponse returns the project binding and safe provider repository refs.
message RepositoryProviderCreateResponse {
  // repository is the pending project binding updated with provider refs and base branch.
  Repository repository = 1;
  // provider_target is the provider repository target derived from the binding.
  RepositoryBootstrapProviderTarget provider_target = 2;
  // base_branch is the provider default branch prepared by repository creation.
  string base_branch = 3;
  // provider_operation_id is the provider-hub operation id when returned.
  optional string provider_operation_id = 4;
  // provider_result_ref is a safe provider result URL or id.
  optional string provider_result_ref = 5;
  // provider_repository_id is the provider-native repository id when known.
  optional string provider_repository_id = 6;
  // provider_web_url is a safe URL to the provider repository.
  optional string provider_web_url = 7;
  // provider_object_id is the provider-native object id when known.
  optional string provider_object_id = 8;
  // provider_version is the provider version or update marker when known.
  optional string provider_version = 9;
}

// CreateRepositoryBootstrapPullRequestRequest prepares project context for an empty-repository bootstrap PR.
message CreateRepositoryBootstrapPullRequestRequest {
  // project_id is the project that owns the repository binding.
  string project_id = 1;
  // repository_id is the project-catalog repository binding id.
  string repository_id = 2;
  // base_branch is the verified project base branch and must match the binding default branch in this slice.
  string base_branch = 3;
  // bootstrap_branch is the branch provider-hub creates or updates.
  string bootstrap_branch = 4;
  // commit_message is the safe commit message for prepared files.
  string commit_message = 5;
  // title is PR/MR title.
  string title = 6;
  // body is PR/MR body.
  string body = 7;
  // draft controls provider draft state when supported.
  bool draft = 8;
  // files are prepared text files. project-catalog does not generate a repository template.
  repeated RepositoryBootstrapFile files = 9;
  // watermark_json is the required platform watermark payload for provider-native PR/MR linking.
  string watermark_json = 10;
  // services_policy links prepared files to a caller-checked services.yaml projection.
  RepositoryBootstrapServicesPolicy services_policy = 11;
  // external_account_id is the provider account selected by caller policy for the write.
  string external_account_id = 12;
  // meta carries idempotency and audit context.
  CommandMeta meta = 13;
}

// RepositoryBootstrapPullRequestResponse returns project and provider refs for the bootstrap PR command.
message RepositoryBootstrapPullRequestResponse {
  // repository is the authoritative project repository binding used for the provider command.
  Repository repository = 1;
  // provider_target is the provider repository target derived from the binding.
  RepositoryBootstrapProviderTarget provider_target = 2;
  // base_branch is the target branch accepted by project-catalog.
  string base_branch = 3;
  // bootstrap_branch is the provider-side bootstrap branch.
  string bootstrap_branch = 4;
  // services_policy_source_path is the checked services.yaml source path.
  string services_policy_source_path = 5;
  // services_policy_content_hash is the checked services.yaml content hash.
  string services_policy_content_hash = 6;
  // provider_operation_id is the provider-hub operation id when available.
  optional string provider_operation_id = 7;
  // provider_result_ref is provider-hub command result ref when available.
  optional string provider_result_ref = 8;
  // provider_work_item_projection_id is provider-hub PR/MR projection id when available.
  optional string provider_work_item_projection_id = 9;
  // provider_web_url is the provider PR/MR URL when available.
  optional string provider_web_url = 10;
  // provider_object_id is the provider-native object id when available.
  optional string provider_object_id = 11;
}

// GetRepositoryRequest reads a repository binding.
message GetRepositoryRequest {
  // repository_id is the repository binding aggregate id.
  string repository_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListRepositoriesRequest lists repositories in a project.
message ListRepositoriesRequest {
  // project_id filters repositories by owner project.
  string project_id = 1;
  // statuses optionally filter repository binding lifecycle.
  repeated RepositoryStatus statuses = 2;
  // page limits response size.
  PageRequest page = 3;
  // meta carries read actor and request context.
  QueryMeta meta = 4;
}

// ListRepositoriesResponse returns repository list.
message ListRepositoriesResponse {
  // repositories are returned in stable server-defined order.
  repeated Repository repositories = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// ImportServicesPolicyRequest imports a checked services.yaml projection.
message ImportServicesPolicyRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // source_repository_id is the repository where source policy was found.
  optional string source_repository_id = 2;
  // source_path is the policy file path.
  string source_path = 3;
  // source_ref is the branch, tag or provider ref used for import.
  optional string source_ref = 4;
  // source_commit_sha is the commit used for checked projection.
  string source_commit_sha = 5;
  // source_blob_sha is the provider file object hash when available.
  optional string source_blob_sha = 6;
  // content_hash is the normalized source content hash.
  string content_hash = 7;
  // validated_payload_json is normalized payload for audit and revalidation.
  string validated_payload_json = 8;
  // service_descriptors are typed descriptors extracted from policy.
  repeated ServiceDescriptor service_descriptors = 9;
  // validation_status is source validation status.
  ServicesPolicyValidationStatus validation_status = 10;
  // meta carries idempotency and audit context.
  CommandMeta meta = 11;
}

// ImportBootstrapServicesPolicyRequest imports a checked services.yaml projection after provider bootstrap PR merge.
message ImportBootstrapServicesPolicyRequest {
  // project_id is the project that owns the repository binding.
  string project_id = 1;
  // repository_id is the project-catalog repository binding id.
  string repository_id = 2;
  // provider_target is the safe provider repository target from provider projection.
  RepositoryBootstrapProviderTarget provider_target = 3;
  // base_branch is the repository binding base branch that received the merge.
  string base_branch = 4;
  // source_ref is the branch, tag or provider ref used for checked import.
  string source_ref = 5;
  // source_commit_sha is the merge commit used for checked projection.
  string source_commit_sha = 6;
  // source_blob_sha is the provider file object hash when available.
  optional string source_blob_sha = 7;
  // source_path is the services.yaml path in the merged commit.
  string source_path = 8;
  // content_hash is the normalized source content hash.
  string content_hash = 9;
  // validated_payload_json is normalized services.yaml payload already checked by the caller contour.
  string validated_payload_json = 10;
  // watermark_json is the parsed platform watermark payload from the merged provider work item.
  string watermark_json = 11;
  // provider_work_item_projection_id is the safe provider-hub PR/MR projection id when known.
  optional string provider_work_item_projection_id = 12;
  // provider_web_url is the safe provider PR/MR URL when known.
  optional string provider_web_url = 13;
  // provider_object_id is the provider-native PR/MR object id when known.
  optional string provider_object_id = 14;
  // merge_observed_at is the provider merge observation time in RFC3339 format when known.
  optional string merge_observed_at = 15;
  // meta carries idempotency, expected repository version and audit context.
  CommandMeta meta = 16;
}

// BootstrapRepositoryMergeSignal is the safe provider-side merge signal used to close repository bootstrap.
message BootstrapRepositoryMergeSignal {
  // signal_id is provider-hub repository_merge_signal id when known.
  optional string signal_id = 1;
  // signal_key is provider-hub idempotency key for this merge signal.
  string signal_key = 2;
  // signal_kind must be bootstrap for this project-catalog command.
  string signal_kind = 3;
  // provider_target is the safe provider repository target from provider projection.
  RepositoryBootstrapProviderTarget provider_target = 4;
  // base_branch is the branch that received the merge.
  string base_branch = 5;
  // source_ref is the provider PR/MR source ref from the safe merge signal; checked import uses base_branch.
  string source_ref = 6;
  // merge_commit_sha is the merge commit observed by provider-hub.
  string merge_commit_sha = 7;
  // source_blob_sha is the provider file object hash when available.
  optional string source_blob_sha = 8;
  // watermark_digest is the provider-hub digest of the parsed platform watermark.
  string watermark_digest = 9;
  // watermark_json is the parsed platform watermark payload from the merged provider work item.
  string watermark_json = 10;
  // provider_work_item_projection_id is the safe provider-hub PR/MR projection id when known.
  optional string provider_work_item_projection_id = 11;
  // provider_web_url is the safe provider PR/MR URL when known.
  optional string provider_web_url = 12;
  // provider_object_id is the provider-native PR/MR object id when known.
  optional string provider_object_id = 13;
  // merge_observed_at is the provider merge observation time in RFC3339 format when known.
  optional string merge_observed_at = 14;
  // merged_at is the provider merge time in RFC3339 format when known.
  optional string merged_at = 15;
}

// CheckedBootstrapServicesPolicyArtifact is the checked services.yaml artifact prepared outside project-catalog.
message CheckedBootstrapServicesPolicyArtifact {
  // artifact_ref is a safe immutable ref to the checked artifact.
  string artifact_ref = 1;
  // artifact_digest is the digest of the checked normalized services.yaml artifact.
  string artifact_digest = 2;
  // artifact_version is the immutable artifact version bound to the merge commit in this slice.
  string artifact_version = 3;
  // source_path is the services.yaml path in the merged commit.
  string source_path = 4;
  // content_hash is the normalized services.yaml source content hash.
  string content_hash = 5;
  // validated_payload_json is normalized services.yaml payload already checked by the caller contour.
  string validated_payload_json = 6;
}

// ReconcileBootstrapMergeSignalRequest imports checked services.yaml from a safe provider bootstrap merge signal.
message ReconcileBootstrapMergeSignalRequest {
  // project_id is the project that owns the repository binding.
  string project_id = 1;
  // repository_id is the project-catalog repository binding id.
  string repository_id = 2;
  // merge_signal is the safe provider-side bootstrap merge signal.
  BootstrapRepositoryMergeSignal merge_signal = 3;
  // checked_policy is the checked services.yaml artifact selected by the caller contour.
  CheckedBootstrapServicesPolicyArtifact checked_policy = 4;
  // meta carries idempotency, expected repository version and audit context.
  CommandMeta meta = 5;
}

// RepositoryAdoptionMergeSignal is the safe provider-side merge signal used to close repository adoption.
message RepositoryAdoptionMergeSignal {
  // signal_id is provider-hub repository_merge_signal id when known.
  optional string signal_id = 1;
  // signal_key is provider-hub idempotency key for this merge signal.
  string signal_key = 2;
  // signal_kind must be adoption for this project-catalog command.
  string signal_kind = 3;
  // provider_target is the safe provider repository target from provider projection.
  RepositoryBootstrapProviderTarget provider_target = 4;
  // base_branch is the branch that received the merge.
  string base_branch = 5;
  // source_ref is the provider PR/MR source ref from the safe merge signal; checked import uses base_branch.
  string source_ref = 6;
  // merge_commit_sha is the merge commit observed by provider-hub.
  string merge_commit_sha = 7;
  // source_blob_sha is the provider file object hash when available.
  optional string source_blob_sha = 8;
  // watermark_digest is the provider-hub digest of the parsed platform watermark.
  string watermark_digest = 9;
  // watermark_json is the parsed platform watermark payload from the merged provider work item.
  string watermark_json = 10;
  // provider_work_item_projection_id is the safe provider-hub PR/MR projection id when known.
  optional string provider_work_item_projection_id = 11;
  // provider_web_url is the safe provider PR/MR URL when known.
  optional string provider_web_url = 12;
  // provider_object_id is the provider-native PR/MR object id when known.
  optional string provider_object_id = 13;
  // merge_observed_at is the provider merge observation time in RFC3339 format when known.
  optional string merge_observed_at = 14;
  // merged_at is the provider merge time in RFC3339 format when known.
  optional string merged_at = 15;
}

// CheckedAdoptionServicesPolicyArtifact is the checked services.yaml artifact selected outside provider-hub.
message CheckedAdoptionServicesPolicyArtifact {
  // artifact_ref is a safe immutable ref to the checked artifact.
  string artifact_ref = 1;
  // artifact_digest is the digest of the checked normalized services.yaml artifact.
  string artifact_digest = 2;
  // artifact_version is the immutable artifact version bound to the merge commit in this slice.
  string artifact_version = 3;
  // source_path is the services.yaml path in the merged commit.
  string source_path = 4;
  // content_hash is the normalized services.yaml source content hash.
  string content_hash = 5;
  // validated_payload_json is normalized services.yaml payload already checked by the caller contour.
  string validated_payload_json = 6;
}

// ReconcileAdoptionMergeSignalRequest imports checked services.yaml from a safe provider adoption merge signal.
message ReconcileAdoptionMergeSignalRequest {
  // project_id is the project that owns the repository binding.
  string project_id = 1;
  // repository_id is the project-catalog repository binding id.
  string repository_id = 2;
  // merge_signal is the safe provider-side adoption merge signal.
  RepositoryAdoptionMergeSignal merge_signal = 3;
  // checked_policy is the checked services.yaml artifact selected by the caller contour.
  CheckedAdoptionServicesPolicyArtifact checked_policy = 4;
  // meta carries idempotency, expected repository version and audit context.
  CommandMeta meta = 5;
}

// BootstrapServicesPolicyImportResponse returns imported policy and activated repository binding state.
message BootstrapServicesPolicyImportResponse {
  // repository is the active repository binding after bootstrap import.
  Repository repository = 1;
  // services_policy is the checked services.yaml projection.
  ServicesPolicy services_policy = 2;
  // source_ref is the accepted provider source ref.
  string source_ref = 3;
  // source_commit_sha is the accepted merge commit.
  string source_commit_sha = 4;
  // summary is a short safe import summary for logs, events and UI.
  string summary = 5;
}

// ServicesPolicyResponse returns services policy state.
message ServicesPolicyResponse {
  // services_policy is the returned checked policy.
  ServicesPolicy services_policy = 1;
}

// GetSelfDeploySignalRequest читает project-side enrichment для provider repository change signal.
message GetSelfDeploySignalRequest {
  // project_id задаёт область project-side binding и checked services.yaml projection.
  string project_id = 1;
  // repository_id опционально сужает ожидаемый repository binding.
  optional string repository_id = 2;
  // provider_signal_id опционально выбирает provider-hub repository change signal id.
  optional string provider_signal_id = 3;
  // provider_signal_key опционально выбирает provider-hub repository change signal idempotency key.
  optional string provider_signal_key = 4;
  // meta содержит read actor и request context.
  QueryMeta meta = 5;
}

// SelfDeploySignalResponse возвращает safe project-side readiness и plan input.
message SelfDeploySignalResponse {
  // status описывает готовность сигнала для agent-manager planning.
  SelfDeploySignalStatus status = 1;
  // signal присутствует, когда project/provider facts безопасно связаны.
  SelfDeploySignal signal = 2;
  // safe_reason объясняет blocked status без raw payloads и секретов.
  optional string safe_reason = 3;
}

// GetSelfDeployBuildPlanRequest читает проверенный build plan из project-owned ServicesPolicy.
message GetSelfDeployBuildPlanRequest {
  // project_id задаёт область checked ServicesPolicy.
  string project_id = 1;
  // repository_id задаёт repository binding для affected services.
  string repository_id = 2;
  // source_ref — branch/ref из ready self-deploy signal.
  string source_ref = 3;
  // merge_commit_sha — commit sha из ready self-deploy signal.
  string merge_commit_sha = 4;
  // provider_signal_ref — stable signal ref из SelfDeployPlan, если известен.
  optional string provider_signal_ref = 5;
  // provider_signal_id — persisted provider signal id, если известен.
  optional string provider_signal_id = 6;
  // provider_signal_key — provider signal idempotency key, если известен.
  optional string provider_signal_key = 7;
  // affected_service_keys — service keys из ready self-deploy signal.
  repeated string affected_service_keys = 8;
  // expected_services_policy_digest — digest checked ServicesPolicy, ожидаемый caller.
  string expected_services_policy_digest = 9;
  // expected_services_policy_fingerprint — fingerprint checked ServicesPolicy, ожидаемый caller.
  optional string expected_services_policy_fingerprint = 10;
  // expected_services_policy_version — policy version, ожидаемая caller.
  optional int64 expected_services_policy_version = 11;
  // meta содержит read actor и request context.
  QueryMeta meta = 12;
  // materialized_build_contexts передаёт context refs/digests от runtime-manager для affected services.
  repeated SelfDeployMaterializedBuildContext materialized_build_contexts = 13;
  // expected_build_plan_fingerprint позволяет вызывающей стороне сверить повтор с ранее выданным recipe/plan.
  optional string expected_build_plan_fingerprint = 14;
}

// SelfDeployBuildPlanResponse возвращает проверенный build plan или безопасную non-ready reason.
message SelfDeployBuildPlanResponse {
  // status описывает готовность build plan.
  SelfDeployBuildPlanStatus status = 1;
  // plan присутствует при ready.
  SelfDeployBuildPlan plan = 2;
  // safe_reason объясняет non-ready status без raw payloads и секретов.
  optional string safe_reason = 3;
}

// GetSelfDeployDeployPlanRequest читает проверенный deploy plan из project-owned ServicesPolicy.
message GetSelfDeployDeployPlanRequest {
  // project_id задаёт область checked ServicesPolicy.
  string project_id = 1;
  // repository_id задаёт repository binding для affected services.
  string repository_id = 2;
  // source_ref — branch/ref из approved self-deploy plan.
  string source_ref = 3;
  // merge_commit_sha — commit sha из approved self-deploy plan.
  string merge_commit_sha = 4;
  // provider_signal_ref — stable signal ref из SelfDeployPlan, если известен.
  optional string provider_signal_ref = 5;
  // affected_service_keys — service keys из approved self-deploy plan.
  repeated string affected_service_keys = 6;
  // expected_services_policy_digest — digest checked ServicesPolicy, ожидаемый caller.
  string expected_services_policy_digest = 7;
  // expected_services_policy_fingerprint — fingerprint checked ServicesPolicy, ожидаемый caller.
  optional string expected_services_policy_fingerprint = 8;
  // expected_services_policy_version — policy version, ожидаемая caller.
  optional int64 expected_services_policy_version = 9;
  // build_outputs передают только safe refs успешных build jobs.
  repeated SelfDeployBuildOutput build_outputs = 10;
  // expected_build_plan_fingerprint связывает deploy с ранее проверенным build plan.
  optional string expected_build_plan_fingerprint = 11;
  // expected_deploy_plan_fingerprint позволяет вызывающей стороне сверить replay.
  optional string expected_deploy_plan_fingerprint = 12;
  // materialized_build_contexts передаёт context refs для manifest bundle refs без provider fetch.
  repeated SelfDeployMaterializedBuildContext materialized_build_contexts = 13;
  // meta содержит read actor и request context.
  QueryMeta meta = 14;
}

// SelfDeployDeployPlanResponse возвращает проверенный deploy plan или безопасную non-ready reason.
message SelfDeployDeployPlanResponse {
  // status описывает готовность deploy plan.
  SelfDeployDeployPlanStatus status = 1;
  // plan присутствует при ready.
  SelfDeployDeployPlan plan = 2;
  // safe_reason объясняет non-ready status без raw payloads и секретов.
  optional string safe_reason = 3;
}

// GetServicesPolicyRequest reads active or concrete services policy.
message GetServicesPolicyRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // services_policy_id optionally selects a concrete policy version.
  optional string services_policy_id = 2;
  // meta carries read actor and request context.
  QueryMeta meta = 3;
}

// ListServiceDescriptorsRequest lists typed descriptors from active policy.
message ListServiceDescriptorsRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // repository_id optionally filters descriptors by repository.
  optional string repository_id = 2;
  // service_keys optionally selects concrete services.
  repeated string service_keys = 3;
  // statuses optionally filter descriptor lifecycle.
  repeated ServiceStatus statuses = 4;
  // page limits response size.
  PageRequest page = 5;
  // meta carries read actor and request context.
  QueryMeta meta = 6;
}

// ListServiceDescriptorsResponse returns service descriptors.
message ListServiceDescriptorsResponse {
  // service_descriptors are returned in stable server-defined order.
  repeated ServiceDescriptor service_descriptors = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// CreatePolicyEditProposalRequest requests a PR-backed services.yaml change.
message CreatePolicyEditProposalRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // repository_id is the repository where services.yaml should be edited.
  string repository_id = 2;
  // source_path is the policy file path.
  string source_path = 3;
  // requested_changes_json is typed proposal payload serialized by caller.
  string requested_changes_json = 4;
  // meta carries idempotency and audit context.
  CommandMeta meta = 5;
}

// PolicyEditProposalResponse returns a policy edit proposal.
message PolicyEditProposalResponse {
  // proposal_id is the project-catalog proposal id.
  string proposal_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id is the target repository id.
  string repository_id = 3;
  // status is a machine-readable proposal status.
  string status = 4;
}

// CreatePolicyOverrideRequest creates an emergency policy override.
message CreatePolicyOverrideRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // target_type classifies overridden policy area.
  PolicyOverrideTargetType target_type = 2;
  // target_id is optional concrete aggregate id.
  optional string target_id = 3;
  // payload_json is the minimum override payload.
  string payload_json = 4;
  // expires_at is the expiration timestamp in RFC3339 format.
  string expires_at = 5;
  // meta carries idempotency and audit context; reason is required.
  CommandMeta meta = 6;
}

// CancelPolicyOverrideRequest cancels an active emergency policy override.
message CancelPolicyOverrideRequest {
  // policy_override_id is the override aggregate id.
  string policy_override_id = 1;
  // meta carries idempotency, expected version and audit context; reason is required.
  CommandMeta meta = 2;
}

// PolicyOverrideResponse returns override state.
message PolicyOverrideResponse {
  // policy_override is the returned override.
  PolicyOverride policy_override = 1;
}

// ListPolicyOverridesRequest lists operator policy overrides.
message ListPolicyOverridesRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // target_types optionally filter overridden policy areas.
  repeated PolicyOverrideTargetType target_types = 2;
  // target_id optionally filters a concrete overridden aggregate.
  optional string target_id = 3;
  // statuses optionally filter override lifecycle when active_only is false.
  repeated PolicyOverrideStatus statuses = 4;
  // active_only returns only active and unexpired overrides.
  bool active_only = 5;
  // page limits response size.
  PageRequest page = 6;
  // meta carries read actor and request context.
  QueryMeta meta = 7;
}

// ListPolicyOverridesResponse returns operator policy overrides.
message ListPolicyOverridesResponse {
  // policy_overrides are returned in stable server-defined order.
  repeated PolicyOverride policy_overrides = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// PutDocumentationSourceRequest creates or updates a documentation source.
message PutDocumentationSourceRequest {
  // documentation_source_id is optional source aggregate id.
  optional string documentation_source_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id is optional repository binding id.
  optional string repository_id = 3;
  // scope_type classifies where the source applies.
  DocumentationScopeType scope_type = 4;
  // scope_id is optional service, dependency or guidance scope id.
  optional string scope_id = 5;
  // local_path is target path in workspace.
  string local_path = 6;
  // access_mode controls whether the source is editable.
  DocumentationAccessMode access_mode = 7;
  // status is source status.
  DocumentationSourceStatus status = 8;
  // meta carries idempotency, optional expected version and audit context.
  CommandMeta meta = 9;
}

// DocumentationSourceResponse returns documentation source state.
message DocumentationSourceResponse {
  // documentation_source is the returned source.
  DocumentationSource documentation_source = 1;
}

// GetDocumentationSourceRequest reads a documentation source.
message GetDocumentationSourceRequest {
  // documentation_source_id is the source aggregate id.
  string documentation_source_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListDocumentationSourcesRequest lists documentation sources.
message ListDocumentationSourcesRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // repository_id optionally filters sources by repository.
  optional string repository_id = 2;
  // scope_type optionally filters source scope.
  optional DocumentationScopeType scope_type = 3;
  // scope_id optionally filters source scope id.
  optional string scope_id = 4;
  // statuses optionally filter source lifecycle.
  repeated DocumentationSourceStatus statuses = 5;
  // page limits response size.
  PageRequest page = 6;
  // meta carries read actor and request context.
  QueryMeta meta = 7;
}

// ListDocumentationSourcesResponse returns documentation sources.
message ListDocumentationSourcesResponse {
  // documentation_sources are returned in stable server-defined order.
  repeated DocumentationSource documentation_sources = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// GetWorkspacePolicyRequest reads agent workspace policy.
message GetWorkspacePolicyRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // repository_ids optionally select repositories.
  repeated string repository_ids = 2;
  // service_keys optionally select services.
  repeated string service_keys = 3;
  // include_guidance_packages controls whether guidance package refs are returned.
  bool include_guidance_packages = 4;
  // meta carries read actor and request context.
  QueryMeta meta = 5;
}

// WorkspacePolicyResponse returns workspace policy.
message WorkspacePolicyResponse {
  // workspace_policy is the returned policy.
  WorkspacePolicy workspace_policy = 1;
}

// PutBranchRulesRequest creates or updates branch rules.
message PutBranchRulesRequest {
  // branch_rules_id is optional branch rules aggregate id.
  optional string branch_rules_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id narrows rules to one repository when set.
  optional string repository_id = 3;
  // pattern is the branch name pattern.
  string pattern = 4;
  // required_checks are provider check names required by policy.
  repeated string required_checks = 5;
  // merge_policy is the allowed merge strategy.
  MergePolicy merge_policy = 6;
  // status is branch rules status.
  BranchRulesStatus status = 7;
  // meta carries idempotency, optional expected version and audit context.
  CommandMeta meta = 8;
}

// BranchRulesResponse returns branch rules state.
message BranchRulesResponse {
  // branch_rules is the returned branch rules.
  BranchRules branch_rules = 1;
}

// GetBranchRulesRequest reads branch rules.
message GetBranchRulesRequest {
  // branch_rules_id is the branch rules aggregate id.
  string branch_rules_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListBranchRulesRequest lists branch rules.
message ListBranchRulesRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // repository_id optionally filters rules by repository.
  optional string repository_id = 2;
  // statuses optionally filter rules lifecycle.
  repeated BranchRulesStatus statuses = 3;
  // page limits response size.
  PageRequest page = 4;
  // meta carries read actor and request context.
  QueryMeta meta = 5;
}

// ListBranchRulesResponse returns branch rules list.
message ListBranchRulesResponse {
  // branch_rules are returned in stable server-defined order.
  repeated BranchRules branch_rules = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// PutReleasePolicyRequest creates or updates release policy.
message PutReleasePolicyRequest {
  // release_policy_id is optional release policy aggregate id.
  optional string release_policy_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // name is the policy display name.
  string name = 3;
  // branch_pattern is release branch pattern.
  string branch_pattern = 4;
  // rollout_strategy is the deployment rollout strategy.
  RolloutStrategy rollout_strategy = 5;
  // rollback_policy is the rollback rule.
  RollbackPolicy rollback_policy = 6;
  // risk_profile_ref references governance risk profile.
  optional string risk_profile_ref = 7;
  // status is release policy status.
  ReleasePolicyStatus status = 8;
  // meta carries idempotency, optional expected version and audit context.
  CommandMeta meta = 9;
}

// ReleasePolicyResponse returns release policy state.
message ReleasePolicyResponse {
  // release_policy is the returned release policy.
  ReleasePolicy release_policy = 1;
}

// GetReleasePolicyRequest reads release policy.
message GetReleasePolicyRequest {
  // release_policy_id is the release policy aggregate id.
  string release_policy_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListReleasePoliciesRequest lists release policies.
message ListReleasePoliciesRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // statuses optionally filter policy lifecycle.
  repeated ReleasePolicyStatus statuses = 2;
  // page limits response size.
  PageRequest page = 3;
  // meta carries read actor and request context.
  QueryMeta meta = 4;
}

// ListReleasePoliciesResponse returns release policies.
message ListReleasePoliciesResponse {
  // release_policies are returned in stable server-defined order.
  repeated ReleasePolicy release_policies = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// PutReleaseLineRequest creates or updates a release line.
message PutReleaseLineRequest {
  // release_line_id is optional release line aggregate id.
  optional string release_line_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // release_policy_id is the source release policy id.
  string release_policy_id = 3;
  // name is the release line name.
  string name = 4;
  // branch_pattern is release branch pattern.
  string branch_pattern = 5;
  // status is release line status.
  ReleasePolicyStatus status = 6;
  // meta carries idempotency, optional expected version and audit context.
  CommandMeta meta = 7;
}

// ReleaseLineResponse returns release line state.
message ReleaseLineResponse {
  // release_line is the returned release line.
  ReleaseLine release_line = 1;
}

// GetReleaseLineRequest reads release line.
message GetReleaseLineRequest {
  // release_line_id is the release line aggregate id.
  string release_line_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListReleaseLinesRequest lists release lines.
message ListReleaseLinesRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // release_policy_id optionally filters lines by release policy.
  optional string release_policy_id = 2;
  // statuses optionally filter line lifecycle.
  repeated ReleasePolicyStatus statuses = 3;
  // page limits response size.
  PageRequest page = 4;
  // meta carries read actor and request context.
  QueryMeta meta = 5;
}

// ListReleaseLinesResponse returns release lines.
message ListReleaseLinesResponse {
  // release_lines are returned in stable server-defined order.
  repeated ReleaseLine release_lines = 1;
  // page describes continuation state.
  PageResponse page = 2;
}

// PutPlacementPolicyRequest creates or updates placement policy.
message PutPlacementPolicyRequest {
  // placement_policy_id is optional placement policy aggregate id.
  optional string placement_policy_id = 1;
  // project_id is the owner project id.
  string project_id = 2;
  // repository_id narrows policy to one repository when set.
  optional string repository_id = 3;
  // service_key narrows policy to one service when set.
  optional string service_key = 4;
  // allowed_cluster_refs contains fleet-manager cluster references.
  repeated string allowed_cluster_refs = 5;
  // status is placement policy status.
  PlacementPolicyStatus status = 6;
  // meta carries idempotency, optional expected version and audit context.
  CommandMeta meta = 7;
}

// PlacementPolicyResponse returns placement policy state.
message PlacementPolicyResponse {
  // placement_policy is the returned placement policy.
  PlacementPolicy placement_policy = 1;
}

// GetPlacementPolicyRequest reads placement policy.
message GetPlacementPolicyRequest {
  // placement_policy_id is the placement policy aggregate id.
  string placement_policy_id = 1;
  // meta carries read actor and request context.
  QueryMeta meta = 2;
}

// ListPlacementPoliciesRequest lists placement policies.
message ListPlacementPoliciesRequest {
  // project_id is the owner project id.
  string project_id = 1;
  // repository_id optionally filters policy by repository.
  optional string repository_id = 2;
  // service_key optionally filters policy by service.
  optional string service_key = 3;
  // statuses optionally filter policy lifecycle.
  repeated PlacementPolicyStatus statuses = 4;
  // page limits response size.
  PageRequest page = 5;
  // meta carries read actor and request context.
  QueryMeta meta = 6;
}

// ListPlacementPoliciesResponse returns placement policies.
message ListPlacementPoliciesResponse {
  // placement_policies are returned in stable server-defined order.
  repeated PlacementPolicy placement_policies = 1;
  // page describes continuation state.
  PageResponse page = 2;
}
