Drive the proto → deploy cascade
When you change soundverse-proto, the
new contract has to reach every consumer: the generated SDKs, the Go data services, the
Python gateway/workers, and the web app. That propagation is partly automated and partly
manual, and knowing which is which is the difference between a clean rollout and a
“deployed but nothing changed” afternoon.
The flow
Section titled “The flow”flowchart TD
dev[Edit proto on a feature branch] --> pr[Open PR]
pr --> ci["ci.yml — buf format + lint + full-generation smoke"]
ci --> merge[Merge to staging]
merge --> rel["staging-release.yml — regenerate + publish SDKs @staging"]
rel --> pub["soundverse-proto-{go,python,web,swift,kotlin}@staging"]
rel --> disp["repository_dispatch: proto_updated → grep '^core' + soundverse-py"]
disp --> pyDirect["Direct Python consumers auto-PR<br/>gateway · identity · billing · storage · soundverse-py"]
pyDirect --> spylock[soundverse-py re-locks + publishes]
spylock --> spydisp["soundverse_updated → tool workers"]
spydisp --> workers["Tool workers auto-PR<br/>agent · sansaarm · stitch · media · gpu"]
disp -.commented out.-> goManual["Go services: core-database · core-mcp<br/>MANUAL ./update-proto.sh"]
class dev,pr,ci,merge frontend
class rel,pub,disp gateway
class pyDirect,spylock,spydisp,workers worker
class goManual external
classDef frontend fill:#6366f1,color:#fff,stroke:#4338ca
classDef gateway fill:#0ea5e9,color:#fff,stroke:#0369a1
classDef worker fill:#10b981,color:#fff,stroke:#047857
classDef external fill:#f59e0b,color:#111,stroke:#b45309
Staging
Section titled “Staging”-
Edit the proto on a feature branch and open a PR.
ci.ymlruns on the PR:bufformat check,buflint, a full-generation smoke, and per-language package smokes (Go / Python / web / Swift / Kotlin). -
Merge to
staging. This triggersstaging-release.yml, which regenerates and publishessoundverse-proto-{go,python,web,swift,kotlin}@staging, then fans out arepository_dispatch(event_type=proto_updated) to every repo matching^coreorsoundverse-py. -
Direct Python consumers auto-PR. On
proto_updated,soundverse-py,core-gateway-consumer,core-identity,core-billing, andcore-storageopenupdate-private-depsPRs. Review and merge. Tool workers bump on a second hop. easy to miss The tool workers (
core-tool-agent/sansaarm/stitch/media/gpu) do not listen forproto_updated. Theirupdate-private-deps.ymltriggers onsoundverse_updated, whichsoundverse-pyfires after it re-locks and publishes. Sosoundverse-pymust land first — then the workers get their PRs.-
Go services are fully manual.
core-databaseandcore-mcphave noupdate-private-depsworkflow, and theirrepository_dispatch: [proto_updated]deploy trigger is commented out — the dispatch is a no-op for Go. Run./update-proto.sh(go get …@staging && go mod tidy), commit, and pushstaging. Deploy core-database first when the change adds a new handler, so it is mounted before consumers call it.
Production
Section titled “Production”Related
Section titled “Related”- Add a field or RPC to a data service — the edit that starts this
- Refresh proto stubs — the per-repo
update-proto.sh - The contract: proto as source of truth — the why
- CI/CD deploy pipeline — how each service deploys