14 proto files across 5 gRPC service domains: - quartermaster/v1 (6): governance, registry, notary, credentials, capabilities, pipelines - bascule/v1 (4): session, command, gateway, ceremony - workspace/v1 (1): workspace management - runner/v1 (2): pipeline execution - schematic/v1 (1): composite meta-artifacts Consumed as a git submodule by guildhouse-platform (Rust) and guildhouse-dashboard (Python). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
424 lines
11 KiB
Protocol Buffer
424 lines
11 KiB
Protocol Buffer
syntax = "proto3";
|
|
package workspace.v1;
|
|
|
|
import "google/protobuf/timestamp.proto";
|
|
|
|
service WorkspaceController {
|
|
// Initialize the canonical repository (first-time setup)
|
|
rpc InitCanonical(InitCanonicalRequest) returns (InitCanonicalResponse);
|
|
|
|
// Get canonical repo status
|
|
rpc GetCanonicalHead(GetCanonicalHeadRequest) returns (GetCanonicalHeadResponse);
|
|
|
|
// Session workspace lifecycle
|
|
rpc CreateWorkspace(CreateWorkspaceRequest) returns (CreateWorkspaceResponse);
|
|
rpc GetWorkspaceStatus(GetWorkspaceStatusRequest) returns (GetWorkspaceStatusResponse);
|
|
rpc DestroyWorkspace(DestroyWorkspaceRequest) returns (DestroyWorkspaceResponse);
|
|
|
|
// Diff and commit
|
|
rpc GetDiff(GetDiffRequest) returns (GetDiffResponse);
|
|
rpc StageFiles(StageFilesRequest) returns (StageFilesResponse);
|
|
rpc Commit(CommitRequest) returns (CommitResponse);
|
|
rpc GetLog(GetLogRequest) returns (GetLogResponse);
|
|
|
|
// Abandon (discard all changes)
|
|
rpc Abandon(AbandonRequest) returns (AbandonResponse);
|
|
|
|
// List active workspaces
|
|
rpc ListWorkspaces(ListWorkspacesRequest) returns (ListWorkspacesResponse);
|
|
|
|
// Get a tar archive of the canonical repo at a specific commit
|
|
rpc GetArchive(GetArchiveRequest) returns (stream ArchiveChunk);
|
|
|
|
// --- Remote sync (Phase 3) ---
|
|
|
|
// Push canonical branch to a configured remote
|
|
rpc PushToRemote(PushToRemoteRequest) returns (PushToRemoteResponse);
|
|
|
|
// Fetch refs from a configured remote into inbound/ branches
|
|
rpc FetchFromRemote(FetchFromRemoteRequest) returns (FetchFromRemoteResponse);
|
|
|
|
// List configured remotes from .guildhouse/remotes.yaml
|
|
rpc ListRemotes(ListRemotesRequest) returns (ListRemotesResponse);
|
|
|
|
// Get sync status between canonical and a remote
|
|
rpc GetRemoteSyncStatus(GetRemoteSyncStatusRequest) returns (GetRemoteSyncStatusResponse);
|
|
|
|
// Report commit status check to a remote provider (GitHub/Forgejo/GitLab)
|
|
rpc ReportStatus(ReportStatusRequest) returns (ReportStatusResponse);
|
|
|
|
// --- Merge operations (Phase 4) ---
|
|
|
|
// Merge an inbound branch into canonical main
|
|
rpc MergeToCanonical(MergeToCanonicalRequest) returns (MergeToCanonicalResponse);
|
|
|
|
// Clean up an inbound branch after merge or rejection
|
|
rpc CleanupInboundBranch(CleanupInboundBranchRequest) returns (CleanupInboundBranchResponse);
|
|
|
|
// List inbound branches (fetched from remotes)
|
|
rpc ListInboundBranches(ListInboundBranchesRequest) returns (ListInboundBranchesResponse);
|
|
|
|
// Lightweight remote HEAD check (ls-remote equivalent — no objects fetched)
|
|
rpc LsRemote(LsRemoteRequest) returns (LsRemoteResponse);
|
|
}
|
|
|
|
// --- Canonical ---
|
|
|
|
message InitCanonicalRequest {
|
|
// Path to a directory of manifests to import as the initial commit.
|
|
// If empty, creates an empty repo with just .guildhouse/ structure.
|
|
string import_path = 1;
|
|
// Commit author
|
|
string author = 2;
|
|
}
|
|
|
|
message InitCanonicalResponse {
|
|
string commit_hash = 1;
|
|
string message = 2;
|
|
}
|
|
|
|
message GetCanonicalHeadRequest {}
|
|
|
|
message GetCanonicalHeadResponse {
|
|
string commit_hash = 1;
|
|
string message = 2;
|
|
string author = 3;
|
|
google.protobuf.Timestamp timestamp = 4;
|
|
uint32 total_files = 5;
|
|
}
|
|
|
|
// --- Session workspace lifecycle ---
|
|
|
|
message CreateWorkspaceRequest {
|
|
string session_id = 1;
|
|
// Branch to base the workspace on (default: "main")
|
|
string base_branch = 2;
|
|
// Git author for commits in this workspace
|
|
string author_name = 3;
|
|
string author_email = 4;
|
|
// If true, workspace is read-only (no branch created, just a checkout)
|
|
bool read_only = 5;
|
|
}
|
|
|
|
message CreateWorkspaceResponse {
|
|
// Filesystem path to the workspace root
|
|
string workspace_path = 1;
|
|
// Git branch name (empty if read_only)
|
|
string branch_name = 2;
|
|
// SHA of the base commit
|
|
string base_commit = 3;
|
|
}
|
|
|
|
message GetWorkspaceStatusRequest {
|
|
string session_id = 1;
|
|
}
|
|
|
|
message GetWorkspaceStatusResponse {
|
|
string session_id = 1;
|
|
string branch_name = 2;
|
|
string base_commit = 3;
|
|
string head_commit = 4;
|
|
uint32 commits_ahead = 5;
|
|
uint32 files_changed = 6;
|
|
uint32 insertions = 7;
|
|
uint32 deletions = 8;
|
|
bool has_uncommitted_changes = 9;
|
|
bool read_only = 10;
|
|
}
|
|
|
|
message DestroyWorkspaceRequest {
|
|
string session_id = 1;
|
|
}
|
|
|
|
message DestroyWorkspaceResponse {
|
|
bool success = 1;
|
|
string message = 2;
|
|
}
|
|
|
|
// --- Diff and commit ---
|
|
|
|
message GetDiffRequest {
|
|
string session_id = 1;
|
|
// If true: diff uncommitted changes only (workspace vs HEAD)
|
|
// If false: diff entire branch vs base (session branch vs main)
|
|
bool uncommitted_only = 2;
|
|
}
|
|
|
|
message GetDiffResponse {
|
|
repeated FileDiff files = 1;
|
|
string base_ref = 2;
|
|
string head_ref = 3;
|
|
uint32 total_insertions = 4;
|
|
uint32 total_deletions = 5;
|
|
}
|
|
|
|
message FileDiff {
|
|
string path = 1;
|
|
// "added", "modified", "deleted", "renamed"
|
|
string status = 2;
|
|
// Unified diff text (empty for binary files)
|
|
string diff_text = 3;
|
|
uint32 insertions = 4;
|
|
uint32 deletions = 5;
|
|
// For renames: the old path
|
|
string old_path = 6;
|
|
}
|
|
|
|
message StageFilesRequest {
|
|
string session_id = 1;
|
|
// File paths to stage (relative to workspace root).
|
|
// Empty = stage all changes (git add -A).
|
|
repeated string paths = 2;
|
|
}
|
|
|
|
message StageFilesResponse {
|
|
uint32 files_staged = 1;
|
|
}
|
|
|
|
message CommitRequest {
|
|
string session_id = 1;
|
|
string message = 2;
|
|
// Override author (if empty, uses the author from CreateWorkspace)
|
|
string author_name = 3;
|
|
string author_email = 4;
|
|
}
|
|
|
|
message CommitResponse {
|
|
string commit_hash = 1;
|
|
uint32 files_committed = 2;
|
|
string message = 3;
|
|
}
|
|
|
|
message GetLogRequest {
|
|
string session_id = 1;
|
|
// Max number of commits to return (default: 20)
|
|
uint32 limit = 2;
|
|
}
|
|
|
|
message GetLogResponse {
|
|
repeated CommitEntry commits = 1;
|
|
}
|
|
|
|
message CommitEntry {
|
|
string hash = 1;
|
|
string short_hash = 2;
|
|
string message = 3;
|
|
string author_name = 4;
|
|
string author_email = 5;
|
|
google.protobuf.Timestamp timestamp = 6;
|
|
uint32 files_changed = 7;
|
|
}
|
|
|
|
// --- Abandon ---
|
|
|
|
message AbandonRequest {
|
|
string session_id = 1;
|
|
}
|
|
|
|
message AbandonResponse {
|
|
bool success = 1;
|
|
uint32 commits_discarded = 2;
|
|
string message = 3;
|
|
}
|
|
|
|
// --- List workspaces ---
|
|
|
|
message ListWorkspacesRequest {}
|
|
|
|
message ListWorkspacesResponse {
|
|
repeated WorkspaceSummary workspaces = 1;
|
|
}
|
|
|
|
message WorkspaceSummary {
|
|
string session_id = 1;
|
|
string branch_name = 2;
|
|
string base_commit = 3;
|
|
string head_commit = 4;
|
|
uint32 commits_ahead = 5;
|
|
bool has_uncommitted_changes = 6;
|
|
bool read_only = 7;
|
|
google.protobuf.Timestamp created_at = 8;
|
|
}
|
|
|
|
// --- Archive ---
|
|
|
|
message GetArchiveRequest {
|
|
// Commit hash to archive (empty = HEAD)
|
|
string commit_hash = 1;
|
|
// Subset of paths to include (empty = all files)
|
|
repeated string paths = 2;
|
|
}
|
|
|
|
message ArchiveChunk {
|
|
bytes data = 1;
|
|
}
|
|
|
|
// --- Remote sync ---
|
|
|
|
message PushToRemoteRequest {
|
|
// Name of the remote (must exist in .guildhouse/remotes.yaml)
|
|
string remote_name = 1;
|
|
// Local branch to push (default: "main")
|
|
string branch = 2;
|
|
// Force push — always false in Phase 3
|
|
bool force = 3;
|
|
}
|
|
|
|
message PushToRemoteResponse {
|
|
bool success = 1;
|
|
// Remote ref that was updated (e.g. "refs/heads/main")
|
|
string remote_ref = 2;
|
|
// Commit hash that was pushed
|
|
string commit_hash = 3;
|
|
string error = 4;
|
|
}
|
|
|
|
message FetchFromRemoteRequest {
|
|
// Name of the remote (must exist in .guildhouse/remotes.yaml)
|
|
string remote_name = 1;
|
|
// Ref patterns to fetch (e.g. "refs/pull/*/head").
|
|
// If empty, uses fetch_refs from remotes.yaml config.
|
|
repeated string ref_patterns = 2;
|
|
}
|
|
|
|
message FetchFromRemoteResponse {
|
|
repeated FetchedRef refs_fetched = 1;
|
|
string error = 2;
|
|
}
|
|
|
|
message FetchedRef {
|
|
// Local ref name (e.g. "inbound/github-origin/pull/42/head")
|
|
string ref_name = 1;
|
|
// Commit hash at the tip of this ref
|
|
string commit_hash = 2;
|
|
// True if this is a newly fetched ref (not previously seen)
|
|
bool is_new = 3;
|
|
}
|
|
|
|
message ListRemotesRequest {}
|
|
|
|
message ListRemotesResponse {
|
|
repeated RemoteInfo remotes = 1;
|
|
}
|
|
|
|
message RemoteInfo {
|
|
string name = 1;
|
|
string url = 2;
|
|
// "github", "forgejo", or "gitlab"
|
|
string provider = 3;
|
|
string push_branch = 4;
|
|
// Last commit hash successfully pushed to this remote (empty if never pushed)
|
|
string last_push_hash = 5;
|
|
// Last time a fetch was performed from this remote
|
|
google.protobuf.Timestamp last_fetch_time = 6;
|
|
}
|
|
|
|
message GetRemoteSyncStatusRequest {
|
|
string remote_name = 1;
|
|
}
|
|
|
|
message GetRemoteSyncStatusResponse {
|
|
string remote_name = 1;
|
|
string canonical_head = 2;
|
|
string remote_head = 3;
|
|
uint32 commits_ahead = 4;
|
|
uint32 commits_behind = 5;
|
|
google.protobuf.Timestamp last_push = 6;
|
|
google.protobuf.Timestamp last_fetch = 7;
|
|
}
|
|
|
|
message ReportStatusRequest {
|
|
// Name of the remote (determines provider + credentials)
|
|
string remote_name = 1;
|
|
// Commit SHA to report status for
|
|
string commit_hash = 2;
|
|
// Status state: "pending", "success", "failure", "error"
|
|
string state = 3;
|
|
// Context label (e.g. "guildhouse/pipeline")
|
|
string context = 4;
|
|
// Human-readable description
|
|
string description = 5;
|
|
// URL to link to (e.g. pipeline run URL)
|
|
string target_url = 6;
|
|
// Attestation hash (hex-encoded) to include in description
|
|
string attestation_hash = 7;
|
|
}
|
|
|
|
message ReportStatusResponse {
|
|
bool success = 1;
|
|
// URL of the created status check (provider-specific)
|
|
string url = 2;
|
|
string error = 3;
|
|
}
|
|
|
|
// --- Merge operations ---
|
|
|
|
message MergeToCanonicalRequest {
|
|
// Branch name to merge (e.g. "inbound/github-origin/pull/42/head")
|
|
string branch_name = 1;
|
|
// Merge commit message
|
|
string merge_message = 2;
|
|
// Author for the merge commit
|
|
string author_name = 3;
|
|
string author_email = 4;
|
|
// Ceremony ID if the merge was approved via Accord
|
|
string ceremony_id = 5;
|
|
}
|
|
|
|
message MergeToCanonicalResponse {
|
|
bool success = 1;
|
|
// New HEAD commit hash after merge
|
|
string new_head = 2;
|
|
// "fast_forward" or "merge_commit"
|
|
string merge_type = 3;
|
|
// Error message (empty on success)
|
|
string error = 4;
|
|
// Number of files changed in the merge
|
|
uint32 files_changed = 5;
|
|
}
|
|
|
|
message CleanupInboundBranchRequest {
|
|
// Branch name to clean up
|
|
string branch_name = 1;
|
|
}
|
|
|
|
message CleanupInboundBranchResponse {
|
|
bool success = 1;
|
|
string message = 2;
|
|
}
|
|
|
|
message ListInboundBranchesRequest {
|
|
// Optional: filter by remote name
|
|
string remote_name = 1;
|
|
}
|
|
|
|
message ListInboundBranchesResponse {
|
|
repeated InboundBranchInfo branches = 1;
|
|
}
|
|
|
|
message InboundBranchInfo {
|
|
string branch_name = 1;
|
|
string commit_hash = 2;
|
|
string remote_name = 3;
|
|
// Original ref (e.g. "pull/42/head")
|
|
string original_ref = 4;
|
|
}
|
|
|
|
// --- Lightweight remote ref check ---
|
|
|
|
message LsRemoteRequest {
|
|
// Name of the remote
|
|
string remote_name = 1;
|
|
// Ref patterns to query (e.g. "refs/heads/main")
|
|
repeated string refs = 2;
|
|
}
|
|
|
|
message LsRemoteResponse {
|
|
repeated RemoteRef refs = 1;
|
|
string error = 2;
|
|
}
|
|
|
|
message RemoteRef {
|
|
string ref_name = 1;
|
|
string commit_hash = 2;
|
|
}
|