Skip to content

[Feature Proposal] Support for Labeling and Filtering Substrate Entities #186

@MushuEE

Description

Currently, the Actor entity in Agent Substrate lacks support for arbitrary key-value metadata (labels/tags). As the platform grows, users and operators need a flexible way to categorize, group, and query active workloads without forcing database-specific indexing implementation requirements.

We propose adding a map<string, string> labels field to the Actor resource, enabling Kubernetes-style label selectors for filtering during ListActors requests.

Note

Performance Characteristic: ListActors is an operational control-plane query (used by command-line tools like kubectl-ate, admin UIs, and operator scripts) and is not on the latency-critical path for routing, scheduling, suspending, or resuming actors. Consequently, in-memory filtering at the service layer is acceptable and does not impact critical path latency.


User Stories & Use Cases

1. Ownership & Multi-Tenancy

  • As a developer using a shared Substrate cluster, I want to filter actor listings to only see my own workloads (e.g. owner=alice).
  • As a team lead, I want to list all actors billed to my team (e.g. team=checkout).

2. Environment & Resource Lifecycle Management

  • As an operator, I want to run a cleanup script that lists all actors in staging (e.g. env=staging) and deletes/suspends them at the end of the day, without affecting production workloads.

3. Business & Workflow Context

  • As a platform engineer, I want to look up an active agent instance by the customer id it is serving (e.g. customer_id=12345) to inspect its status or troubleshoot a support ticket.

4. Scheduler Placement constraints (Future proofing)

  • As a scheduler developer, I want actors to carry constraints (e.g. gpu=required, region=us-central) so that the orchestrator can schedule them onto matching worker pods.

Proposed Design

1. Protobuf API Changes

We will update pkg/proto/ateapipb/ateapi.proto to include a labels map in the Actor message and the creation requests, along with a string-based label_selector for query filtering.

message Actor {
  ...
  // Labels associated with the actor.
  map<string, string> labels = 12;
}

message CreateActorRequest {
  ...
  // Optional labels to apply to the actor upon creation.
  map<string, string> labels = 4;
}

message ListActorsRequest {
  ...
  // An optional Kubernetes-style label selector query string (e.g. "env=production,app=billing").
  string label_selector = 3;
}

2. Database-Agnostic Filtering

To keep the persistence layer pluggable and simple:

  • The Database Interface (store.Interface) will remain simple and only handle standard paginated key scanning. It will not know about the filter criteria.
  • The Service Layer (controlapi.ListActors) will fetch the page of raw actors and apply the filter evaluation in memory using the Go k8s.io/apimachinery/pkg/labels package.
  • Since our Redis storage driver uses protojson for marshaling/unmarshaling, the new labels field will automatically persist to Redis without requiring schema changes or updates to Redis Lua scripts.

Implementation Plan

  1. Update pkg/proto/ateapipb/ateapi.proto and re-generate Go protobuf bindings.
  2. Update the persistence layer interface and implementations to support setting and retrieving labels.
  3. Integrate k8s.io/apimachinery/pkg/labels at the service layer in cmd/ateapi/internal/controlapi/list_actors.go to filter list results before returning them.
  4. Add unit and integration tests covering label assignment, persistence, and selector querying.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions