From f94e8ec96784dc5362f48a4ad4ed7b10c72c83d9 Mon Sep 17 00:00:00 2001 From: Steve Cliff Date: Mon, 4 May 2026 00:33:51 +0100 Subject: [PATCH] api+agent: document protocol-version stability and forget back-compat decisions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit version.go: add a comment block explaining why Phase 5's wire changes (CommandRunPayload, ConfigUpdatePayload, RepoStatsPayload reshapes) did not bump CurrentProtocolVersion — lockstep deploy, no rolling-upgrade path, smoke env restage enforces it. Notes where a version bump to 2 would be required if a multi-version path is ever introduced. cmd/agent/main.go: document why the JobForget handler hard-errors on empty ForgetGroups rather than falling back to a single-policy form. The maintenance ticker is the only writer and always populates the field; the fallback was specced but skipped given lockstep deploy. --- cmd/agent/main.go | 7 +++++++ internal/api/version.go | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 6f8a229..d401640 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -336,6 +336,13 @@ func (d *dispatcher) runJob(ctx context.Context, p api.CommandRunPayload, tx wsc }() case api.JobForget: if len(p.ForgetGroups) == 0 { + // Hard-error rather than fall back to a single-policy form: + // the server-side dispatch path (maintenance ticker) is the + // only writer of forget command.run today, and it always + // populates ForgetGroups. A backwards-compatible single- + // policy fallback was specced but skipped — see the + // Phase 5 plan rationale and version.go's lockstep-deploy + // note for why. return fmt.Errorf("forget: command.run carried no forget_groups (server didn't populate them)") } groups := make([]restic.ForgetGroup, 0, len(p.ForgetGroups)) diff --git a/internal/api/version.go b/internal/api/version.go index 1e9d1f5..0720162 100644 --- a/internal/api/version.go +++ b/internal/api/version.go @@ -12,3 +12,15 @@ const CurrentProtocolVersion = 1 // server accepts in a hello. Agents below this are disconnected with // a structured error pointing at the upgrade docs. const MinAgentProtocolVersion = 1 + +// Phase 5 (P2R-03..P2R-08, branch p2r-phase5-maintenance, 2026-05) reshaped +// CommandRunPayload (RetentionPolicy removed, ForgetGroups added, RequiresAdminCreds added), +// ConfigUpdatePayload (Slot added), and RepoStatsPayload (full reshape). +// The protocol version was deliberately NOT bumped because: +// 1. This project deploys agent and server in lockstep from the same release. +// 2. There is no supported "rolling upgrade" path with mixed agent/server versions. +// 3. The smoke env restage block in CLAUDE.md restages the agent binary on +// every server build for exactly this reason. +// +// If a multi-version protocol path is ever introduced, every Phase 5 wire +// change is a breaking change and the version must bump to 2 at that time.