@@ -42,7 +42,7 @@ func TestRegisterManifestPostsServiceManifest(t *testing.T) {
4242 },
4343 Now : now ,
4444 })
45- if state .RuntimeState != RegistrationRegistered || state .StatusCode != http .StatusOK || state .RemoteSessionID != "remote-sess" || state .RegistrationID != "reg-1" || state .ProtocolVersion != "ccr.remote.v1" || state .WebSocketURL != "wss://remote/ws" || state .PollURL != "https://remote/events" || state .LeaseRenewURL != "https://remote/leases/renew?token=secret" {
45+ if state .RuntimeState != RegistrationRegistered || state .StatusCode != http .StatusOK || state .RemoteSessionID != "remote-sess" || state .RegistrationID != "reg-1" || state .ProtocolVersion != RemoteProtocolVersionV1 || state .WebSocketURL != "wss://remote/ws" || state .PollURL != "https://remote/events" || state .LeaseRenewURL != "https://remote/leases/renew?token=secret" {
4646 t .Fatalf ("registration state = %#v" , state )
4747 }
4848 if len (state .Capabilities ) != 2 || state .Capabilities [0 ] != "websocket_protocol" || state .Capabilities [1 ] != "lease_renew" {
@@ -90,14 +90,46 @@ func TestRegisterManifestAcceptsWrappedResponse(t *testing.T) {
9090 },
9191 Now : now ,
9292 })
93- if state .RuntimeState != RegistrationRegistered || state .RemoteSessionID != "remote-wrapped" || state .RegistrationID != "reg-wrapped" || state .ProtocolVersion != "ccr.remote.v2" || state .WebSocketURL != "wss://remote/wrapped/ws" || state .PollURL != "https://remote/wrapped/events" || state .LeaseRenewURL != "https://remote/wrapped/leases/refresh" || state .Message != "registered" {
93+ if state .RuntimeState != RegistrationRegistered || state .RemoteSessionID != "remote-wrapped" || state .RegistrationID != "reg-wrapped" || state .ProtocolVersion != RemoteProtocolVersionV2 || state .WebSocketURL != "wss://remote/wrapped/ws" || state .PollURL != "https://remote/wrapped/events" || state .LeaseRenewURL != "https://remote/wrapped/leases/refresh" || state .Message != "registered" {
9494 t .Fatalf ("registration state = %#v" , state )
9595 }
9696 if len (state .Capabilities ) != 2 || state .Capabilities [0 ] != "remote_trigger" || state .Capabilities [1 ] != "lease_refresh" {
9797 t .Fatalf ("registration state = %#v" , state )
9898 }
9999}
100100
101+ func TestRegisterManifestRejectsUnsupportedProtocolVersion (t * testing.T ) {
102+ now := time .Date (2026 , 6 , 17 , 11 , 4 , 0 , 0 , time .UTC )
103+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
104+ w .Header ().Set ("content-type" , "application/json" )
105+ _ , _ = w .Write ([]byte (`{
106+ "remoteSessionId":"remote-future",
107+ "protocolVersion":"ccr.remote.v99",
108+ "capabilities":["websocket_protocol"],
109+ "websocketUrl":"wss://remote/future/ws?token=secret",
110+ "pollUrl":"https://remote/future/events?token=secret",
111+ "leaseRenewUrl":"https://remote/future/leases/renew?token=secret"
112+ }` ))
113+ }))
114+ defer server .Close ()
115+
116+ state := RegisterManifest (context .Background (), RegistrationOptions {
117+ RegistrationURL : server .URL + "/register" ,
118+ Manifest : Manifest {
119+ SessionID : "sess_future" ,
120+ EnvironmentID : "env-prod" ,
121+ Services : []Service {{Name : "daemon" , RuntimeState : "running" }},
122+ },
123+ Now : now ,
124+ })
125+ if state .RuntimeState != RegistrationFailed || state .StatusCode != http .StatusOK || state .ProtocolVersion != "ccr.remote.v99" || ! strings .Contains (state .Error , "unsupported remote protocol version" ) || ! strings .Contains (state .Error , RemoteProtocolVersionV1 ) || ! strings .Contains (state .Error , RemoteProtocolVersionV2 ) {
126+ t .Fatalf ("registration state = %#v" , state )
127+ }
128+ if state .RegisteredAt != "" || state .WebSocketURL != "" || state .PollURL != "" || state .LeaseRenewURL != "" || strings .Contains (state .Error , "token=secret" ) {
129+ t .Fatalf ("unsupported state leaked usable endpoint or secret = %#v" , state )
130+ }
131+ }
132+
101133func TestRegisterManifestHandlesDisabledAndFailedState (t * testing.T ) {
102134 now := time .Date (2026 , 6 , 17 , 11 , 5 , 0 , 0 , time .UTC )
103135 manifest := Manifest {SessionID : "sess_remote" , EnvironmentID : "env-prod" }
@@ -118,7 +150,7 @@ func TestRegisterManifestHandlesDisabledAndFailedState(t *testing.T) {
118150func TestWriteAndLoadRegistrationState (t * testing.T ) {
119151 path := filepath .Join (t .TempDir (), "sess_remote" , registrationFileName )
120152 state := DisabledRegistrationState (Manifest {SessionID : "sess_remote" }, "/state/remote-service.json" , time .Date (2026 , 6 , 17 , 11 , 10 , 0 , 0 , time .UTC ))
121- state .ProtocolVersion = "ccr.remote.v1"
153+ state .ProtocolVersion = RemoteProtocolVersionV1
122154 state .Capabilities = []string {"websocket_protocol" , "lease_renew" }
123155 state .LeaseRenewURL = "https://remote/leases/renew"
124156 if err := WriteRegistrationState (path , state ); err != nil {
@@ -128,7 +160,7 @@ func TestWriteAndLoadRegistrationState(t *testing.T) {
128160 if err != nil {
129161 t .Fatal (err )
130162 }
131- if loaded .SessionID != "sess_remote" || loaded .RuntimeState != RegistrationDisabled || loaded .ManifestPath != "/state/remote-service.json" || loaded .ProtocolVersion != "ccr.remote.v1" || loaded .LeaseRenewURL != "https://remote/leases/renew" || len (loaded .Capabilities ) != 2 {
163+ if loaded .SessionID != "sess_remote" || loaded .RuntimeState != RegistrationDisabled || loaded .ManifestPath != "/state/remote-service.json" || loaded .ProtocolVersion != RemoteProtocolVersionV1 || loaded .LeaseRenewURL != "https://remote/leases/renew" || len (loaded .Capabilities ) != 2 {
132164 t .Fatalf ("loaded = %#v" , loaded )
133165 }
134166 missing , err := LoadRegistrationState (filepath .Join (t .TempDir (), registrationFileName ))
0 commit comments