User Story
As a contributor changing proto definitions, I want to know immediately if my changes affect any SDK, so that I can regenerate the stubs myself or trust that SDK maintainers will be notified automatically. Contributors shouldn't need to understand every SDK's internals to make a proto change.
As an SDK maintainer, I want to be notified when proto changes introduce fields or RPCs that my SDK's converter layer doesn't yet expose, enabling planned and prioritized SDK update work without manually tracking every proto change.
Problem Statement
OpenShell maintains four SDKs (Go, TypeScript, Python, Rust) across different teams. Proto file changes have varying impacts per SDK:
Go is unique in committing generated proto stubs to the repository. Go's source-level dependency model (go get clones and compiles sources directly) necessitates this. When protos change, committed stubs must be regenerated and re-committed. The existing go:proto:check CI task verifies stub consistency but is a simple pass/fail gate without notifications.
TypeScript, Python, and Rust all generate stubs at build time and gitignore them. TypeScript uses buf generate (output to src/gen/, gitignored). Python runs grpc_tools.protoc via a python:proto task before builds. Rust uses tonic-prost-build in a build.rs script at compile time. Stub drift is structurally impossible for these three SDKs.
All four SDKs share a deeper problem: each has a hand-written domain type layer (converters, typed wrappers, From impls) mapping proto types into idiomatic language constructs. A new proto field compiles and tests pass, but the field is silently absent from the SDK's public API. SDK consumers discover missing fields only through trial and error. This "converter coverage gap" grows silently as proto definitions evolve.
| SDK |
Stubs Committed? |
Generation Tool |
Domain Type Layer |
Stub Drift Risk |
| Go |
Yes (source-level deps require it) |
buf generate |
types/ + converter/ |
Yes |
| TypeScript |
No (src/gen/ gitignored) |
buf generate |
Curated API + raw escape hatch |
No |
| Python |
No (_proto/ gitignored) |
grpc_tools.protoc |
sandbox.py dataclass wrappers |
No |
| Rust |
No (compile-time build.rs) |
tonic-prost-build |
types.rs with From impls |
No |
Impact / Why This Matters
Current behavior: Proto changes land without any notification to SDK maintainers. For Go, contributors must know to regenerate and commit stubs. For all four SDKs, new proto fields are silently ignored by the domain type layer.
Current workaround: SDK maintainers manually monitor proto changes by watching the commit log. This is error-prone and doesn't scale.
Why the workaround is insufficient: As the contributor base grows, proto changes come from many people who may not be aware of SDK implications. SDK consumers depend on proto fields being exposed through the SDK. Silent gaps create downstream surprises.
Proposed Design
Stub drift detection + issue lifecycle
Scope: Go SDK (the only SDK committing generated stubs). Infrastructure is designed to be extensible if other SDKs' build models change.
- Per-SDK mise tasks (
go:proto:drift) that regenerate stubs in a temp directory and compare against committed files, outputting structured JSON
- A PR-triggered GitHub workflow annotating PRs with drift warnings (non-blocking, informational). Contributors see messages like: "Your proto change affects SDK stubs. The Go SDK stubs are 3 files behind."
- A daily cron workflow that:
- Runs drift detection for each SDK
- If drift is found, runs a build verification pipeline (regenerate, build, test)
- Creates or updates a GitHub issue per SDK (deduplicated by
sdk:{sdk}:sync label, matching the repo's existing area:sdk:{language} convention)
- Auto-closes issues when drift resolves
- A Python script for issue body generation and lifecycle management via
gh
This makes contributions transparent without blocking anyone. Contributors see warnings; SDK maintainers get actionable issues with fix commands.
Extensibility
The system should use a config-driven approach where adding a new SDK requires only:
- A drift detection mise task for that language
- A config entry with display name, source directories, and build/test tasks
This pattern scales to all current and future SDKs.
Future extensions
Converter coverage analysis — compare proto message fields against what each SDK's converter/domain-type layer actually maps, reporting fields present in proto but absent from SDK type mappings. This would detect the deeper "business logic gap" that stub comparison cannot catch. Scope would cover all four SDKs.
Acceptance Criteria
Alternatives Considered
Fail CI on proto drift: Rejected. This would block proto contributors until every affected SDK is updated. Contributors should be able to land proto changes without understanding SDK internals. SDK maintenance is the SDK maintainer's responsibility, triggered by notifications.
Wiki dashboard: Considered and deferred. Wiki pages have low discoverability. PR annotations and auto-filed issues are more visible to those who need to act.
Integrate into existing branch-checks.yml: Worth discussing. A "Proto Drift" row alongside existing checks increases visibility. A separate workflow is easier to iterate on initially and can be promoted later.
Extend stub drift to TypeScript/Python/Rust: Not needed. All three generate stubs at build time and gitignore them, making stub drift structurally impossible. Go is the only SDK where stubs are committed. All four SDKs would benefit from the converter coverage analysis extension.
cc @maxdubrinsky @drew @mrunalp @Gkrumbach07 @rhuss
User Story
As a contributor changing proto definitions, I want to know immediately if my changes affect any SDK, so that I can regenerate the stubs myself or trust that SDK maintainers will be notified automatically. Contributors shouldn't need to understand every SDK's internals to make a proto change.
As an SDK maintainer, I want to be notified when proto changes introduce fields or RPCs that my SDK's converter layer doesn't yet expose, enabling planned and prioritized SDK update work without manually tracking every proto change.
Problem Statement
OpenShell maintains four SDKs (Go, TypeScript, Python, Rust) across different teams. Proto file changes have varying impacts per SDK:
Go is unique in committing generated proto stubs to the repository. Go's source-level dependency model (
go getclones and compiles sources directly) necessitates this. When protos change, committed stubs must be regenerated and re-committed. The existinggo:proto:checkCI task verifies stub consistency but is a simple pass/fail gate without notifications.TypeScript, Python, and Rust all generate stubs at build time and gitignore them. TypeScript uses
buf generate(output tosrc/gen/, gitignored). Python runsgrpc_tools.protocvia apython:prototask before builds. Rust usestonic-prost-buildin abuild.rsscript at compile time. Stub drift is structurally impossible for these three SDKs.All four SDKs share a deeper problem: each has a hand-written domain type layer (converters, typed wrappers,
Fromimpls) mapping proto types into idiomatic language constructs. A new proto field compiles and tests pass, but the field is silently absent from the SDK's public API. SDK consumers discover missing fields only through trial and error. This "converter coverage gap" grows silently as proto definitions evolve.buf generatetypes/+converter/src/gen/gitignored)buf generaterawescape hatch_proto/gitignored)grpc_tools.protocsandbox.pydataclass wrappersbuild.rs)tonic-prost-buildtypes.rswithFromimplsImpact / Why This Matters
Current behavior: Proto changes land without any notification to SDK maintainers. For Go, contributors must know to regenerate and commit stubs. For all four SDKs, new proto fields are silently ignored by the domain type layer.
Current workaround: SDK maintainers manually monitor proto changes by watching the commit log. This is error-prone and doesn't scale.
Why the workaround is insufficient: As the contributor base grows, proto changes come from many people who may not be aware of SDK implications. SDK consumers depend on proto fields being exposed through the SDK. Silent gaps create downstream surprises.
Proposed Design
Stub drift detection + issue lifecycle
Scope: Go SDK (the only SDK committing generated stubs). Infrastructure is designed to be extensible if other SDKs' build models change.
go:proto:drift) that regenerate stubs in a temp directory and compare against committed files, outputting structured JSONsdk:{sdk}:synclabel, matching the repo's existingarea:sdk:{language}convention)ghThis makes contributions transparent without blocking anyone. Contributors see warnings; SDK maintainers get actionable issues with fix commands.
Extensibility
The system should use a config-driven approach where adding a new SDK requires only:
This pattern scales to all current and future SDKs.
Future extensions
Converter coverage analysis — compare proto message fields against what each SDK's converter/domain-type layer actually maps, reporting fields present in proto but absent from SDK type mappings. This would detect the deeper "business logic gap" that stub comparison cannot catch. Scope would cover all four SDKs.
Acceptance Criteria
Alternatives Considered
Fail CI on proto drift: Rejected. This would block proto contributors until every affected SDK is updated. Contributors should be able to land proto changes without understanding SDK internals. SDK maintenance is the SDK maintainer's responsibility, triggered by notifications.
Wiki dashboard: Considered and deferred. Wiki pages have low discoverability. PR annotations and auto-filed issues are more visible to those who need to act.
Integrate into existing
branch-checks.yml: Worth discussing. A "Proto Drift" row alongside existing checks increases visibility. A separate workflow is easier to iterate on initially and can be promoted later.Extend stub drift to TypeScript/Python/Rust: Not needed. All three generate stubs at build time and gitignore them, making stub drift structurally impossible. Go is the only SDK where stubs are committed. All four SDKs would benefit from the converter coverage analysis extension.
cc @maxdubrinsky @drew @mrunalp @Gkrumbach07 @rhuss