Skip to content

Activity lists: proto updates for server-side sort/filter/pagination + auth (runners/threads/identity/gateway) #133

@rowan-stein

Description

@rowan-stein

User request

Implement the API/proto surface needed to move Console Activity lists (Workloads / Storage / Threads) to server-side sort/filter/pagination with deterministic cursor pagination, plus updated authorization relations.

Source spec: https://github.com/agynio/architecture/blob/main/changes/2026-04-24-activity-server-side-lists.md

Specification (architecture/product)

From:

  • changes/2026-04-24-activity-server-side-lists.md
  • architecture/runners.md#listworkloads-request-shape + #listvolumes-request-shape
  • architecture/threads.md#listorganizationthreads-request-shape
  • product/console/console.md (Workloads/Storage/Threads)

Key decisions to reflect in protos:

  • All three lists require deterministic cursor pagination with stable secondary sort by id (cursor includes tie-breaker).
  • Search applies only to Storage/Volumes: case-insensitive substring match on “volume name”.
  • Storage status enum is canonical Runners VolumeStatus: provisioning | active | deprovisioning | deleted | failed.
  • Volume list items include attachments[] { kind, id, name } and volume_name so Console never renders raw IDs.
  • Auth model changes (handled in agynio/authorization) require callers to hold:
    • can_view_workloads on org for Workloads list
    • can_view_volumes on org for Storage list
    • can_view_threads on org for Threads list (expanded to include cluster admins)

NOTE: Volume “name” mapping

Current agents.v1.Volume proto has description but no explicit name field. Console currently displays Volume.description as the human label in some views.

Until/unless a dedicated Volume.name is introduced, treat ListVolumes/Activity volume_name as:

  • primary: agents.Volume.description
  • fallback: agents.Volume.mount_path (if description is empty)

Work items

Runners API (proto/agynio/api/runners/v1/runners.proto)

  • Extend ListWorkloadsRequest to match the documented list envelope:
    • organization_id (required at runtime)
    • filter.* (agent_id_in, runner_id_in, status_in, started_after, started_before, pending_sample)
    • sort.* (field: started|agent|runner|status|duration; direction: asc|desc)
    • page_token, page_size
    • Keep existing fields for backwards compatibility if needed; mark deprecated if appropriate.
  • Extend ListVolumesRequest similarly:
    • filter.* (status_in, runner_id_in, attached_to_kind_in, pending_sample, volume_name_substring)
    • sort.* (field: name|size|status|created; direction)
  • Extend response item messages:
    • Workload: add agent_name, runner_name
    • Volume: add volume_name and repeated Attachment attachments
    • Define Attachment + AttachmentKind enum (agent|mcp|hook)

Threads API (proto/agynio/api/threads/v1/threads.proto)

  • Add new RPC + messages per spec:
    • ListOrganizationThreads(ListOrganizationThreadsRequest) returns (ListOrganizationThreadsResponse)
    • request includes organization_id, filter.*, sort.*, page_token, page_size
    • response includes threads[] and next_page_token
  • Participant enrichment:
    • extend Participant with nickname (string) so list responses can include @nickname.
  • Keep existing GetOrganizationThreads RPC for compatibility (Gateway currently exposes it); implementers may delegate internally.

Identity API (proto/agynio/api/identity/v1/identity.proto)

  • Add a reverse/batch nickname lookup needed to enrich thread participants:
    • e.g. BatchGetNicknames / ResolveIdentityNicknames style RPC
    • Input: organization_id + identity_ids[]
    • Output: repeated results { identity_id, nickname } (missing nicknames are omitted or returned empty; define behavior)

Gateway API surface (proto/agynio/api/gateway/v1/*.proto)

  • Expose the new Threads.ListOrganizationThreads RPC through the Gateway (likely alongside existing GetOrganizationThreads for compatibility).

Buf / codegen

  • Update buf modules as needed and ensure downstream repos can update their buf.lock + regenerate.

Acceptance

  • Protos compile and are compatible with downstream regeneration.
  • New/updated request/response shapes support the server-side list behaviors described in the spec, including deterministic pagination tie-breakers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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