cargoless-proto — the cross-crate contract for cargoless.
This crate is the seam the daemon (watcher/analyzer/model), the build
pipeline + CAS (build/cargoless-cas), the dev server (server), the CLI, and
future remote backends communicate through. Cross-boundary data flows as
these types; nobody reaches across a module boundary with a direct call.
Authoring this jointly and freezing it early is the whole point of Plane
CWDL-19 (D8) — the two-engineer split silently diverges otherwise.
Why dependency-free and serde-free in v0 (decision of record)
v0 is single-machine, single-process: every consumer of these types links
cargoless-proto directly and passes them in-memory (channels / function args).
Nothing crosses a process or network boundary, so nothing needs to be
serialized. Adding serde now would (a) put a non-trivial dependency in the
crate every other crate depends on, slowing the cold build that AC#1/#2 are
measured against, and (b) freeze a wire format we have no v0 consumer for.
When a boundary genuinely needs serialization (the dev-server↔browser reload
channel speaks WebSocket — decision D3 — and remote CAS is a v1 want),
the owning crate adds serde here behind an off-by-default serde feature
and derives it on exactly the types that cross that boundary. The contract
shapes below are designed so that bolt-on is additive, never a reshape.
The data-flow at a glance
watcher → analyzer → model ──StateEvent──▶ everyone (verdict stream)
│
└─on BecameGreen──▶ BuildTrigger ─▶ build/CAS
│
server ◀──BuildResult── build/CAS ◀─────┘
The model is the single source of truth for "what works"; the build/CAS layer is the single source of truth for "is this exact input already built". Everything else subscribes.