| workspaces | array of WorkspaceId | Which workspaces to search. Empty means every workspace this store holds. Default [] |
|---|
| has | string or null | Only tasks carrying this attribute key (koru.due, or a custom definition's key). Default null |
|---|
| missing | string or null | Only tasks not carrying this key. Default null |
|---|
| tags | array of string | Only tasks carrying any of these tags, each a TagId in storage form. Ids, never names - the tag table owns names and rename must not change what a saved query matches. Default [] |
|---|
| priority | string or null | Only tasks whose koru.priority equals this token (low | medium | high | urgent). Default null |
|---|
| min_priority | string or null | Only tasks whose koru.priority is this token or more important - the semantic order low < medium < high < urgent, never the alphabetic one. Default null |
|---|
| due | DueFilter or null | Which koru.due values match, stated per temporal type. Default null |
|---|
| bucket | string or null | Only tasks in one agenda bucket - today, next, upcoming, later or completed (SPEC §7). Usable only with [`bucket_windows`](Self::bucket_windows), which is where the reader's zone was resolved; naming one without the other is a 400, as is a token that is not one of the five. A bucket is never persisted and never guessed - a store that invented today's date would be wrong by morning and wrong in another country. A bucket names a lifecycle, so it supersedes [`lifecycle`](Self::lifecycle). Completed is one of the five and the other four are open by rule 1 of the bucket function, so ANDing the two fields would answer bucket: "completed" with an empty page under the default lifecycle - a silent trap on the most obvious request. When this field is present, the query's lifecycle is not applied. Default null |
|---|
| bucket_windows | BucketWindows or null | The reader's zone, already resolved into days and instants - required by [bucket](Self::bucket) and by group_by: "bucket". Default null |
|---|
| completed_on_or_after | string or null | Hide tasks completed before this day - a canonical YYYY-MM-DD, inclusive, which the caller computed from its own today and [COMPLETED_WINDOW_DAYS]. It applies to completed rows and to nothing else, so it narrows the Completed queue and leaves the four open ones exactly as they were. A task the store cannot date is kept. A completion recorded before this build carries no day, and a store that cannot tell how old something is must not call it old: hiding those would take work out of sight that nobody could ask for back. They age out as they are reopened, finished again, or taken off Tasks. Default null |
|---|
| recently_completed_since | string or null | Keep tasks completed on or after this day where they were, rather than only in the Completed queue: a canonical YYYY-MM-DD the caller computed from its own today. What it loosens is where a completed task is listed, not what a task is. A queue places a row by its due when this covers it, so something ticked this morning stays on the page it was ticked on, struck through, instead of vanishing; a list shows it beside the open work in it. Nothing else about the row changes, and the row is still in the Completed queue as well - the two pages are two questions. The counts do not carry it, deliberately: a queue's number is how much open work is in it, and ticking something should make that number go down rather than leave it where it was. Default null |
|---|
| list | string or null | Only tasks in this list - a ListId in storage form. A list is a filter, not a place (SPEC §8): membership is one koru.list value on the task, so this is one more predicate over one more attribute and ANDs with every filter above it. Ids, never names - the workspace's list table owns names, and renaming a list must not change what a saved query matches. An id no table names matches nothing. Default null |
|---|
| group_by | string or null | Ask for corpus-wide counts beside the page. list or bucket; absent means no groups, and the response's groups is empty. An unknown token is a 400, never a silently ungrouped answer. The attribute query's rule, applied here: a client can count a page itself, and what it cannot do is count the rows it did not fetch - so a sidebar's "14" comes from its own statement over the same filter rather than from the page above it. bucket requires [bucket_windows](Self::bucket_windows) and answers five rows per workspace, one per bucket - the rail's Today 5 · 3 overdue, Next 12, Upcoming 40, Later 9, Completed 118. It partitions by lifecycle (Completed is one of the five), so it does not apply [lifecycle](Self::lifecycle) either, for [bucket](Self::bucket)'s reason.
Default null |
|---|
| overdue | DueFilter or null | Which dues count as overdue, stated per temporal type - used only to split groups, never to filter rows. Overdue is a fact about the reader's display zone (SPEC §7) and the store carries no timezone database, so the caller computes the windows and sends them: typically dates.before = today and instants.before_ms = now. Absent means every group's overdue is zero, which is the honest answer to a question nobody asked. Default null |
|---|
| lifecycle | LifecycleFilter | Open, completed, or both. Absent means open - a task list answers what should I do next, and absence of koru.task_state is itself open. Default "open" |
|---|
| include_trashed | boolean | Also return tasks sitting in their document's own bin, each flagged with [TaskRow::in_trash]. Off by default; on is how a binned task stays restorable from a Tasks surface. It does not govern binned documents: those rows are always returned, flagged with [TaskRow::document_trashed]. Default false |
|---|
| sort | TaskSort | due, priority or modified. Absent means due - soonest first, undated last.
Default "due" |
|---|
| limit | integer (uint, >= 0) | Rows per page, clamped by the store; see [MAX_LIMIT]. Default 100 |
|---|
| after | string or null | The task: reference the previous page ended on, exclusive. Keyset, never an offset. A Tasks view re-queries at every local midnight and on every resume, and an offset page silently repeats or skips a row when anything inserts above it. A reference that no longer matches the filter is not an error: the answer comes from the top with [TaskQueryResponse::restarted] set. Default null |
|---|
| covering | array of RevisionRequirement | Writes this answer must include for the caller to trust it. A surface that has just written a document and re-asks the read model can be answered from a projection that has not seen the write yet - the store projects asynchronously and coalesces. Naming the write lets the answer say so through [TaskQueryResponse::covered], and the caller can ask again rather than draw a number it knows is behind. Optional and additive. Absent means the caller is not waiting on anything; an older client never sends it. At most [MAX_COVERING] entries; a malformed one refuses the request rather than answering uncovered, because a malformed requirement is a client bug and a quiet answer would hide it. Pagination is untouched. Default [] |
|---|