Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions