guildhouse-proto/workspace/v1/workspace.proto
Tyler King 2720a631b8 Initial: Guildhouse protobuf definitions
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>
2026-02-26 10:29:06 -05:00

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;
}