v0.82.0: X-Felhom-Agent-Version response header — the controller capability channel
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -128,7 +128,12 @@ type Options struct {
|
||||
// HostID is this agent's host id — surfaced in a data-bearing-format pending-op so the operator
|
||||
// signs an op bound to THIS host (slice 10B anti-retarget). Optional (only used for the hint).
|
||||
HostID string
|
||||
Logger *slog.Logger
|
||||
// AgentVersion is this agent's build version (main.version). When set, EVERY local-API response
|
||||
// carries it in the X-Felhom-Agent-Version header — the controller's capability channel: its
|
||||
// Supports() compares this against a per-feature MinAgent table instead of route-probing
|
||||
// (v0.82.0; the probe stays as the fallback for header-less agents). Optional.
|
||||
AgentVersion string
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// defaultBackupCadence is the fallback /backup/due window when none is configured.
|
||||
@@ -183,8 +188,9 @@ type Server struct {
|
||||
staleLock StaleLockController // F2-b startup stale-lock recovery (optional)
|
||||
host storage.HostReader // role classification source (optional; defaults to ProcHostReader)
|
||||
|
||||
hostMetrics HostMetricsProvider // slice 9 (optional)
|
||||
hostID string // slice 10B: for the data-bearing-format pending-op hint
|
||||
hostMetrics HostMetricsProvider // slice 9 (optional)
|
||||
hostID string // slice 10B: for the data-bearing-format pending-op hint
|
||||
agentVersion string // v0.82.0: the X-Felhom-Agent-Version response header value
|
||||
|
||||
// reresolveWipe performs the [AGENT-001] anti-retarget re-resolution before an
|
||||
// inline customer-confirmed wipe (durable id → current device, re-derive+match,
|
||||
@@ -274,6 +280,7 @@ func NewServer(o Options) (*Server, error) {
|
||||
host: o.HostReader,
|
||||
hostMetrics: o.HostMetrics,
|
||||
hostID: o.HostID,
|
||||
agentVersion: o.AgentVersion,
|
||||
jobs: map[int]*backupJob{},
|
||||
swapInFlight: map[int]bool{},
|
||||
}
|
||||
@@ -336,7 +343,17 @@ func (s *Server) Handler() http.Handler {
|
||||
mux.HandleFunc("POST /escrow/stage-secret", s.withGuest(s.handleStageEscrowSecret))
|
||||
// fork-4 hygiene: wipe the staged secret once escrowed (controller calls this on confirm). Idempotent.
|
||||
mux.HandleFunc("DELETE /escrow/stage-secret", s.withGuest(s.handleWipeStagedEscrowSecret))
|
||||
return mux
|
||||
|
||||
// v0.82.0 version channel: EVERY response (any route, any status — including auth failures)
|
||||
// carries X-Felhom-Agent-Version, so the controller learns the agent version passively from its
|
||||
// ordinary traffic and can capability-gate by comparison instead of route-probing. Header-less
|
||||
// (pre-0.82) agents keep working — the controller falls back to the probe.
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.agentVersion != "" {
|
||||
w.Header().Set("X-Felhom-Agent-Version", s.agentVersion)
|
||||
}
|
||||
mux.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// Run binds the bridge socket, serves TLS, and shuts down gracefully on ctx cancellation. It
|
||||
|
||||
Reference in New Issue
Block a user