fix(docs): correct two statements that contradict what they describe (#7092)

Both surfaced on the v0.8.12 release PR (#7090). Neither is on code this
branch's earlier work touched, but both are the same defect class it was
already correcting — documentation that states something the code does not do.

v2 knowledge documents list: the JSDoc said `workspaceId` "is dropped for the
same reason as on the sibling chunk list". The sibling genuinely drops it — its
query type does not even carry the field. This list keeps it, and an inline
comment five lines below the binding says so and explains why: dropping it
changes the fingerprint, so every cursor minted beforehand would be refused
with a message telling the caller they altered a filter they never sent. The
JSDoc now states the retention and defers to that note for the reason.

v2-api-conventions skill: "Fifteen lists take the pair" — parsing
`CURSOR_BINDINGS` gives 19 of 27 paged lists binding both `sortBy` and
`sortOrder`. A hard-coded count drifts every time a list gains sorting, which
is how this one went stale, so it now points at the test as the authoritative
set instead of restating a number.
This commit is contained in:
Waleed
2026-08-25 19:19:58 -07:00
committed by GitHub
parent 4508ec75d2
commit 7e7e941829
2 changed files with 8 additions and 5 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ Every paged list's binding is declared in `lib/api/contracts/v2/__tests__/list-p
Return `nextCursor: null` on the last page and only then. Never construct a cursor client-side.
**Ordering is `sortBy` + `sortOrder`, except where there is nothing to sort by.** Fifteen lists take the pair. Exactly one — `GET /workflows/{workflowId}/runs` — has a single sortable column (start time), so there is no `sortBy` to pair with and the direction rides on a single `order` param; `sortBy`/`sortOrder` are not accepted there. That is the *only* sanctioned deviation, and it is documented in its contract. A new list picks the pair. Do not "fix" it by accepting `sortOrder` as an alias: an alias is a second spelling of one thing with undefined precedence when both arrive, which is its own inconsistency.
**Ordering is `sortBy` + `sortOrder`, except where there is nothing to sort by.** Nearly every paged list takes the pair; `CURSOR_BINDINGS` in `contracts/v2/__tests__/list-pagination.test.ts` is the authoritative set. Exactly one — `GET /workflows/{workflowId}/runs` — has a single sortable column (start time), so there is no `sortBy` to pair with and the direction rides on a single `order` param; `sortBy`/`sortOrder` are not accepted there. That is the *only* sanctioned deviation, and it is documented in its contract. A new list picks the pair. Do not "fix" it by accepting `sortOrder` as an alias: an alias is a second spelling of one thing with undefined precedence when both arrive, which is its own inconsistency.
`GET /logs` was the second exception until it absorbed `POST /logs/query`. That fold is the cautionary tale for this rule: the justification for the `order` spelling was "logs have exactly one sortable column", and a second endpoint sorting the same rows four ways had already disproved it. When a rule's premise is contradicted by another endpoint on the same collection, fix the premise rather than documenting the exception.
@@ -54,10 +54,13 @@ const MAX_FILE_SIZE = MAX_KNOWLEDGE_DOCUMENT_FILE_SIZE
* stating it or omitting it selects the same documents. A scope part the query
* ignores refuses a cursor for a page that did not move.
*
* `workspaceId` is dropped for the same reason as on the sibling chunk list:
* the sequence is one knowledge base, named by the path param this already
* binds, and the query's workspace is asserted scope that authorization refuses
* before paging rather than a filter that can select a different sequence.
* `workspaceId` is asserted scope rather than a filter, for the same reason as
* on the sibling chunk list: the sequence is one knowledge base, named by the
* path param this already binds, and authorization refuses any other workspace
* before paging. Unlike that list it is nonetheless kept in the fingerprint —
* see the note at the binding below. Dropping it would be correct in principle
* and inert in effect, but it would refuse every cursor minted before the
* change.
*/
function documentCursorFilters(
knowledgeBaseId: string,