picatz / picatz/flowstate

proto/server: one list contract — `List`, `ListSchedules`, `GetTimeline` and `GetCatalog` page four different ways, none declares an order, and only one takes a filter

Open
#1,664 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

cli design engine kind/decision
Dominant language
Go
Stars
9
Forks
0
Avg merge
3h 3m
Merged PRs (30d)
509

Description

Observed behavior

At eb8172f:

RPC Page shape More? Order Filter
List (service.proto:688-748) page_size, opaque page_token next_page_token none declared CEL over a vocabulary documented in the field comment
ListSchedules (schedule.proto:265-279) none truncated bool "whatever order the cluster returned them" none
GetTimeline (service.proto:1130-1201) max_entries, after_event_id truncated bool event order none
GetCatalog (service.proto:1300) none none none none

grep -rn order_by proto/ returns nothing. A page walk without a declared sort key cannot promise a stable boundary, which is the hazard next_page_token's own comment spends a paragraph on. The filter vocabulary is prose in one field's comment (service.proto:713-747), so an agent building a filter parses a docstring; the schedule list has no filter, so flow schedule list cannot narrow at all. A client library implements three cursor loops and three "is there more" predicates for one service.

The CLI already pays: flow list --all walks pages, flow schedule list reads one truncated page, and the MCP tools inherit each shape verbatim.

Desired outcome

One contract, stated once and applied to every list-shaped RPC:

  • page_size (bounded, server-clamped) and an opaque page_token, next_page_token empty at the end, on every list.
  • order_by with a closed set of keys per resource and a default that is stable (start_time desc, workflow_id for runs), declared in the request message's comment and enforced.
  • filter as CEL on every list, with the bound names published as a machine-readable declaration (GetCatalog already carries the CEL environment for expressions; the filter vocabularies belong beside it) so an editor and an agent read the same list the server compiles against.
  • truncated retired in favor of the token, since a truncated page with no cursor cannot be resumed.

Acceptance criteria

  • ListSchedulesRequest and GetTimelineRequest take the same paging fields ListRequest does; flow schedule list --filter 'state == "paused"' works.
  • A test walks each list under a page size of 1 and asserts every item appears exactly once, in the declared order, on a fixture of at least three items.
  • The filter vocabularies are served by one RPC and docs/reference/ renders them from it.

Constraints and dependencies

  • List's in-process tenant filtering and its scan bounds (#1384) are unchanged by this; ordering must be the visibility store's order or the contract says pages are ordered within the scanned window only.
  • GetTimeline's cursor (#1119, #1135 in the proto comments) becomes the page token.
  • Additive fields; truncated is deprecated before removal per #722.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with service.proto sections 688-748, 1130-1201, and 1300, then compare schedule.proto lines 265-279 with ListRequest. Trace flow list --all and flow schedule list to understand their current pagination behavior. Done means every list passes the page-size-1 uniqueness and ordering checks, schedule filtering works, and one RPC supplies vocabularies rendered by docs/reference/.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend-api-design, cli, documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.