refactor: move proto/ to vantage-shared

vantage.proto documents the hand-written types in shared/grpc/pb, and
nothing compiles it. Keeping it in a different repository from the Go
types it describes meant the one rule holding them together — add the
message to both in the same commit — could not be followed at all.

server's rebuild trigger loses proto/, which it only carried as
insurance against exactly that split.
This commit is contained in:
2026-09-08 08:44:47 +00:00
parent f9dec9b230
commit 1c6d9e8495
3 changed files with 25 additions and 415 deletions
+20 -18
View File
@@ -68,7 +68,6 @@ vantage/
│ ├── app/login, app/setup # unauthed routes
│ ├── components/ # ui/, workflows/, monitors/, Sidebar
│ └── lib/ # api client, guac console, query client
├── proto/vantage/v1/vantage.proto
├── installer/ # Windows: setup.ps1, nssm.exe, WiX .wxs
├── deploy/ # docker-compose.yml, agent.service
└── .gitea/workflows/ # agent-release.yml, server-deploy.yml
@@ -101,7 +100,8 @@ The rest lives in that repository's own CLAUDE.md.
email system: transport plus templates), `license/` (payload, sign, verify,
trusted keys, plans), `models/` (Instance, User, Settings), `provision/`,
`backup/`, `cryptobox/`, `indexes/`, `grpc/pb` + `grpc/codec`, and
`cmd/lkctl/`. Three modules here depend on it — `server`, `agent` and
`cmd/lkctl/`, and `proto/vantage/v1/vantage.proto`, which documents `grpc/pb`
and moved there to sit beside it. Three modules here depend on it — `server`, `agent` and
`vantagectl` — each pinning a version in its own `go.mod`, as do
`vantage-admin` and `vantage-site`. It was a
directory in this repository until it was extracted with its history; the
@@ -470,25 +470,27 @@ container's stdout is arbitrary and cannot be masked the way a workflow's can.
is in `ScopedCollections` (which `scopedCollectionsForPurge` derives from). There
is no history: a workload list is state, not a record.
**`proto/vantage/v1/vantage.proto` is documentation, not a generator input.**
`shared/grpc/pb` is hand-written JSON-tagged structs over the custom codec in
`shared/grpc/codec`, and it is **one** package shared by both sides — a message
added to it must be added to the `.proto` in the same commit, but there is no
longer a second Go copy to keep in step. There used to be two
**The wire contract is not in this repository at all.** `shared/grpc/pb` is
hand-written JSON-tagged structs over the custom codec in `shared/grpc/codec`,
and `proto/vantage/v1/vantage.proto` is documentation of them rather than a
generator input — nothing compiles it. Both live in `vantage-shared`, together,
because that co-location is the only thing making "add the message to both in
the same commit" possible.
It is **one** `pb` package serving both sides. There used to be two
(`agent/internal/grpc/pb` and `server/internal/grpc/pb`) and they had already
drifted: the agent's `UnimplementedVantageServer` was three methods stale and
carried no `ReportWorkloads` at all. The agent links the server half as dead
code, which the linker drops.
This makes `agent` the **fifth** consumer of `shared/`, and the wire contract now
lives outside this repository entirely: a message added to `vantage-shared` is
not a message either side has until its pin is bumped. What that buys is that
the mismatch is a compile error rather than two copies that both compiled and
disagreed on the wire. What it costs is ordering — a wire change needs a
`vantage-shared` release, then a pin bump in `server/` (live at the next push to
main) and a pin bump in `agent/` (live at the next `agent/v*` tag). The
server-ahead-of-fleet gap existed before too; it is now explicit in two `go.mod`
files instead of implicit in a shared directory.
A message added to `vantage-shared` is not a message either side has until its
pin is bumped. What that buys is a mismatch that is a compile error rather than
two copies that both compiled and disagreed on the wire. What it costs is
ordering — **a wire change is three steps**: release `vantage-shared`, bump the
pin in `server/` (live at the next push to main), bump the pin in `agent/` (live
only at the next `agent/v*` tag). The control plane runs ahead of the fleet in
between, which was true before too; it is now explicit in two `go.mod` files
rather than implicit in a shared directory.
### Status pages
@@ -943,7 +945,7 @@ keeps succeeding and the fleet list still shows the server `active`. The agent's
watchdog arms only **after** it has seen a first ping, so an older server that
sends none is treated as working rather than put into a reconnect loop.
Key-state polling stays on the 30s `SyncKeys` interval. Full message definitions live in `proto/vantage/v1/vantage.proto`.
Key-state polling stays on the 30s `SyncKeys` interval. Full message definitions live in `vantage-shared`, in `proto/vantage/v1/vantage.proto` beside the `grpc/pb` types it describes.
---
@@ -1341,7 +1343,7 @@ cd /opt/vantage && docker compose -f deploy/docker/docker-compose.yml pull && \
| Image | Rebuilds when |
| ---------------------------- | -------------------------------- |
| `server` | `server/`, `proto/`, `go.work` |
| `server` | `server/`, `go.work` |
| `web` | `web/` only |
**No path in this table names `shared/` any more**, and no fan-out rule replaces