From 5ef7c191d9e53e4789757f0203111065f6171bc9 Mon Sep 17 00:00:00 2001 From: PengFei Bai Date: Thu, 23 Jul 2026 16:32:23 +0800 Subject: [PATCH 1/2] deps: bump substrate to 961883a8 (imagecache Phase 1), adapt name-based actor API Bump github.com/agent-substrate/substrate from 3cb7433bd8a8 to 961883a86749 (agent-substrate/substrate#467, on-disk layer-deduplicated image cache + overlayfs rootfs; memorypullcache removed). Root-cures the atelet OOM cycle (substrate#437 / feifeigood/agentfleet#294) and drops oci_unpack from 15-20s to single-digit ms on resume. The bump is wire-breaking: actors and atespaces are now addressed by name-based ObjectRef/ResourceMetadata instead of ActorRef/ActorId, and CreateActor/CreateAtespace return the resource directly. Adapt the three consumers accordingly: - internal/k8s/ate/client.go: wrap create requests in Actor/Atespace with ResourceMetadata; ObjectRef for resume/suspend; CreateActor now returns *ateapipb.Actor. - internal/harness/substrate/substrate.go: GetActorId -> Metadata.Name in the authoritative-resume identity check. - internal/harness/harnesstest/harnesstest.go: mock Control server updated to the new RPC signatures. Plan: feifeigood/agentfleet#369 (P0). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_017TK34TZokEcfPq5JdbUVWo --- go.mod | 8 +++---- go.sum | 24 ++++++++++----------- internal/harness/harnesstest/harnesstest.go | 16 +++++++------- internal/harness/substrate/substrate.go | 4 ++-- internal/k8s/ate/client.go | 18 ++++++++++------ 5 files changed, 37 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 73c022fa..d6397586 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( charm.land/huh/v2 v2.0.3 charm.land/lipgloss/v2 v2.0.3 cloud.google.com/go/compute/metadata v0.9.0 - github.com/agent-substrate/substrate v0.0.0-20260706222328-3cb7433bd8a8 + github.com/agent-substrate/substrate v0.0.0-20260723041539-961883a86749 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.10.0 github.com/spf13/cobra v1.10.2 @@ -62,9 +62,9 @@ require ( go.opentelemetry.io/otel/metric v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect golang.org/x/net v0.55.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/text v0.39.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect modernc.org/libc v1.70.0 // indirect diff --git a/go.sum b/go.sum index a5bc044b..47fc2c9e 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/agent-substrate/substrate v0.0.0-20260706222328-3cb7433bd8a8 h1:tUeBjLs9TJgIWfML2dlZ3UOFG3dacbwrIYkas2ctBgY= -github.com/agent-substrate/substrate v0.0.0-20260706222328-3cb7433bd8a8/go.mod h1:2cvSnnHPwZRAhkrC2LH1bQd1tQBfL3p+zU6pZiHBUkA= +github.com/agent-substrate/substrate v0.0.0-20260723041539-961883a86749 h1:sRSrgODafA5Sh4EEZSrOLdUwoAdfx9iL/o0WXbV3mnw= +github.com/agent-substrate/substrate v0.0.0-20260723041539-961883a86749/go.mod h1:F8PNLu8RH9XvziamlvdoJsXz5dK94giNJuPBQI2QjFQ= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= @@ -157,21 +157,21 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= -golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= -golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= +golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= +golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= diff --git a/internal/harness/harnesstest/harnesstest.go b/internal/harness/harnesstest/harnesstest.go index 8ff9e2fe..3472c1e8 100644 --- a/internal/harness/harnesstest/harnesstest.go +++ b/internal/harness/harnesstest/harnesstest.go @@ -53,23 +53,23 @@ type MockControlServer struct { SuspendErr error // returned from SuspendActor when non-nil } -func (f *MockControlServer) CreateAtespace(_ context.Context, req *ateapipb.CreateAtespaceRequest) (*ateapipb.CreateAtespaceResponse, error) { - return &ateapipb.CreateAtespaceResponse{Atespace: &ateapipb.Atespace{Name: req.GetName()}}, nil +func (f *MockControlServer) CreateAtespace(_ context.Context, req *ateapipb.CreateAtespaceRequest) (*ateapipb.Atespace, error) { + return &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: req.GetAtespace().GetMetadata().GetName()}}, nil } -func (f *MockControlServer) CreateActor(_ context.Context, req *ateapipb.CreateActorRequest) (*ateapipb.CreateActorResponse, error) { +func (f *MockControlServer) CreateActor(_ context.Context, req *ateapipb.CreateActorRequest) (*ateapipb.Actor, error) { f.mu.Lock() - f.createCalls = append(f.createCalls, req.GetActorRef().GetName()) + f.createCalls = append(f.createCalls, req.GetActor().GetMetadata().GetName()) f.mu.Unlock() if f.CreateErr != nil { return nil, f.CreateErr } - return &ateapipb.CreateActorResponse{Actor: &ateapipb.Actor{ActorId: req.GetActorRef().GetName()}}, nil + return &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: req.GetActor().GetMetadata().GetName()}}, nil } func (f *MockControlServer) ResumeActor(_ context.Context, req *ateapipb.ResumeActorRequest) (*ateapipb.ResumeActorResponse, error) { f.mu.Lock() - f.resumeCalls = append(f.resumeCalls, req.GetActorRef().GetName()) + f.resumeCalls = append(f.resumeCalls, req.GetActor().GetName()) resumeIP := f.ResumeIP if len(f.ResumeIPs) > 0 { index := min(len(f.resumeCalls)-1, len(f.ResumeIPs)-1) @@ -79,12 +79,12 @@ func (f *MockControlServer) ResumeActor(_ context.Context, req *ateapipb.ResumeA if f.ResumeNilActor { return &ateapipb.ResumeActorResponse{}, nil } - return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{ActorId: req.GetActorRef().GetName(), AteomPodIp: resumeIP}}, nil + return &ateapipb.ResumeActorResponse{Actor: &ateapipb.Actor{Metadata: &ateapipb.ResourceMetadata{Name: req.GetActor().GetName()}, AteomPodIp: resumeIP}}, nil } func (f *MockControlServer) SuspendActor(_ context.Context, req *ateapipb.SuspendActorRequest) (*ateapipb.SuspendActorResponse, error) { f.mu.Lock() - f.suspendCalls = append(f.suspendCalls, req.GetActorRef().GetName()) + f.suspendCalls = append(f.suspendCalls, req.GetActor().GetName()) f.mu.Unlock() if f.SuspendErr != nil { return nil, f.SuspendErr diff --git a/internal/harness/substrate/substrate.go b/internal/harness/substrate/substrate.go index 43cf7b4b..20dcf1fc 100644 --- a/internal/harness/substrate/substrate.go +++ b/internal/harness/substrate/substrate.go @@ -224,8 +224,8 @@ func (h *SubstrateHarness) resumeWorkerAddr(ctx context.Context, conversationID if actor == nil { return "", fmt.Errorf("received nil actor in response for %s", conversationID) } - if actor.GetActorId() != conversationID { - return "", fmt.Errorf("received actor %s while resuming %s", actor.GetActorId(), conversationID) + if actor.GetMetadata().GetName() != conversationID { + return "", fmt.Errorf("received actor %s while resuming %s", actor.GetMetadata().GetName(), conversationID) } if actor.GetAteomPodIp() == "" { return "", fmt.Errorf("actor %s has no active worker IP address", conversationID) diff --git a/internal/k8s/ate/client.go b/internal/k8s/ate/client.go index 81a5c061..d9697480 100644 --- a/internal/k8s/ate/client.go +++ b/internal/k8s/ate/client.go @@ -58,16 +58,20 @@ func NewClient(ns, template, target string, opts ...grpc.DialOption) (*Client, e } // CreateActor creates a new actor. -func (c *Client) CreateActor(ctx context.Context, id string) (*ateapipb.CreateActorResponse, error) { +func (c *Client) CreateActor(ctx context.Context, id string) (*ateapipb.Actor, error) { client := ateapipb.NewControlClient(c.conn) // TODO(wjjclaud): Configure atespace in manifests instead of reusing the namespace. - if _, err := client.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{Name: c.namespace}); err != nil && status.Code(err) != codes.AlreadyExists { + if _, err := client.CreateAtespace(ctx, &ateapipb.CreateAtespaceRequest{ + Atespace: &ateapipb.Atespace{Metadata: &ateapipb.ResourceMetadata{Name: c.namespace}}, + }); err != nil && status.Code(err) != codes.AlreadyExists { return nil, fmt.Errorf("error when calling Control.CreateAtespace: %w", err) } resp, err := client.CreateActor(ctx, &ateapipb.CreateActorRequest{ - ActorRef: &ateapipb.ActorRef{Atespace: c.namespace, Name: id}, - ActorTemplateNamespace: c.namespace, - ActorTemplateName: c.template, + Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: c.namespace, Name: id}, + ActorTemplateNamespace: c.namespace, + ActorTemplateName: c.template, + }, }) if err != nil { return nil, fmt.Errorf("error when calling Control.CreateActor: %w", err) @@ -80,7 +84,7 @@ func (c *Client) CreateActor(ctx context.Context, id string) (*ateapipb.CreateAc func (c *Client) ResumeActor(ctx context.Context, id string) (*ateapipb.ResumeActorResponse, error) { client := ateapipb.NewControlClient(c.conn) resp, err := client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{ - ActorRef: &ateapipb.ActorRef{Atespace: c.namespace, Name: id}, + Actor: &ateapipb.ObjectRef{Atespace: c.namespace, Name: id}, }) if err != nil { return nil, fmt.Errorf("error when calling Control.ResumeActor: %w", err) @@ -92,7 +96,7 @@ func (c *Client) ResumeActor(ctx context.Context, id string) (*ateapipb.ResumeAc func (c *Client) SuspendActor(ctx context.Context, id string) (*ateapipb.SuspendActorResponse, error) { client := ateapipb.NewControlClient(c.conn) resp, err := client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{ - ActorRef: &ateapipb.ActorRef{Atespace: c.namespace, Name: id}, + Actor: &ateapipb.ObjectRef{Atespace: c.namespace, Name: id}, }) if err != nil { return nil, fmt.Errorf("error when calling Control.SuspendActor: %w", err) From 8e54acb96c511468d5bcad97b74b187fa5bcfebc Mon Sep 17 00:00:00 2001 From: PengFei Bai Date: Sat, 25 Jul 2026 08:10:21 +0800 Subject: [PATCH 2/2] deps: advance substrate pin to 76bac5d0 (post-Phase-1 fixes) Second bump within #369 P1 soak window. Absorbs five fixes on top of imagecache Phase 1 (961883a8), stopping deliberately before the 07-24 afternoon batch (mTLS #237, external volumes #405) which has zero soak: - #498 async worker release uses background ctx (zombie-worker fix) - #508 workflow_pause crash when pod is gone - #499 k8sjwt: skip unusable keys in JWKS discovery - #505 valkey cert reload before expiry - #510 redis not-found error fix (also carries #482 Lock API auto-renew rework, in between) No ax code changes needed: none of these touch the ate client API. go build / go vet / go test -race ./... all green (13 packages). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_017TK34TZokEcfPq5JdbUVWo --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d6397586..f7167720 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( charm.land/huh/v2 v2.0.3 charm.land/lipgloss/v2 v2.0.3 cloud.google.com/go/compute/metadata v0.9.0 - github.com/agent-substrate/substrate v0.0.0-20260723041539-961883a86749 + github.com/agent-substrate/substrate v0.0.0-20260724043042-76bac5d05142 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.10.0 github.com/spf13/cobra v1.10.2 diff --git a/go.sum b/go.sum index 47fc2c9e..b9140b62 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/agent-substrate/substrate v0.0.0-20260723041539-961883a86749 h1:sRSrgODafA5Sh4EEZSrOLdUwoAdfx9iL/o0WXbV3mnw= -github.com/agent-substrate/substrate v0.0.0-20260723041539-961883a86749/go.mod h1:F8PNLu8RH9XvziamlvdoJsXz5dK94giNJuPBQI2QjFQ= +github.com/agent-substrate/substrate v0.0.0-20260724043042-76bac5d05142 h1:V8zSqH4uc1eWhmxh8j65tJ0PPIE0FkzMQzK6kFoYOUQ= +github.com/agent-substrate/substrate v0.0.0-20260724043042-76bac5d05142/go.mod h1:F8PNLu8RH9XvziamlvdoJsXz5dK94giNJuPBQI2QjFQ= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o=