Define archive control v1 protocol

This commit is contained in:
2026-07-22 11:59:57 +00:00
commit 7652262b4c
25 changed files with 1333 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# archive-control-proto
Source-of-truth protobuf contract for Archive Control clients and the Titan
control daemon. Implementations exchange canonical protobuf JSON as one text
message per WebSocket frame.
Upstream: `cabbage/archive-control-proto`
## Contract overview
- `common.proto`: protocol versioning, roles, health, and stable error codes
- `resource.proto`: v1/v2 torrent identity, selected-file sets, trees, and
placements
- `route.proto`: discovered and automatically provisioned pairwise Syncthing
routes
- `transfer.proto`: the protobuf-JSON on-disk transfer manifest and ready marker
- `job.proto`: immutable job requests, runtime states, steps, progress, archive
coverage, and eviction
- `inventory.proto`: scoped, chunked, on-demand inventory/tree responses
- `client.proto`: capabilities, registration, active-job cursors, and heartbeat
- `control.proto`: durable commands, acknowledgements, job events, snapshots,
and route updates
- `envelope.proto`: the only top-level WebSocket application message
## Wire rules
1. A new connection's first application message is `RegisterRequest`.
2. The pre-shared token appears only in that request. It must not be logged.
3. A server command is delivered at least once. Clients durably deduplicate
`command_id` and return `DUPLICATE` for a replayed accepted command.
4. `CommandAck` means durable acceptance, not operation completion.
5. Job events have monotonically increasing global per-job sequences. A command
carries the accepted sequence base and grants one client the event-writer
lease; a gap requires `JobSnapshot` reconciliation before further
destructive transitions.
6. UUIDs use lowercase canonical text. Info hashes use validated lowercase hex.
7. `SelectionSet.ranges` are inclusive, sorted, non-overlapping, and coalesced.
8. Receivers ignore unknown JSON fields for compatible minor versions. They
reject an unknown required command/job operation.
9. Published field numbers and enum values are never reused. Removed values are
reserved in the change that removes them.
10. Implementations cap an envelope at the negotiated maximum and keep streamed
inventory chunks below that value.
## Dockerized tooling
The host remains a thin editor. Buf runs in Docker and writes as the calling
UID/GID:
```bash
./scripts/buf.sh format
./scripts/buf.sh lint
./scripts/buf.sh build
./scripts/validate-examples.sh
./scripts/buf.sh generate
```
An equivalent `Makefile` is provided for environments where `make` is already
available; it is not required on the thin development host.
Generated Python bindings are copied into and committed by consumer
repositories with the exact proto release/commit recorded in their generated
header. `gen/` is intentionally ignored here.
Before releasing a compatible update:
```bash
./scripts/buf.sh breaking '.git#tag=v0.1.0'
```
## JSON examples
`examples/v1/` contains representative canonical protobuf JSON for
registration, inventory, route setup, assignment, progress, commit,
cancellation, eviction, and reconnect reconciliation. They are protocol
fixtures, not hand-maintained alternative schemas.