Fix pagination in exemption fetching behaviour in STO#175
Fix pagination in exemption fetching behaviour in STO#175anuragtiwari005 wants to merge 2 commits into
Conversation
979533b to
b05d805
Compare
There was a problem hiding this comment.
Stale comment
Findings
Important:
src/registry/extractors.ts
The new_nextPageHintis not self-consistent for filtered exemption listings. It only reconstructsstatusand omits the activesearchfilter, so following the hint after a search-scoped page can fetch a different result set than the one the user is paging through.Important:
src/registry/toolsets/sto.ts,src/tools/harness-list.ts
The STO-specific pagination default is being recovered by rewriting the sharedharness_listinputs after Zod has already applied the genericsize=20default. That means an explicitsize: 20request is silently changed to5, and pagination values that arrive throughfiltersare normalized instead of failing loudly. This breaks the shared-tool contract and makes the fix broader than a narrowly scoped STO pagination adjustment.Missing Tests
- A tool-level
harness_listregression forresource_type="security_exemption"that covers omitted size =>5, explicit custom sizes (especially explicit20) remaining intact, andskipCompactpreserving the projected STO fields.- An extractor/preflight regression that verifies
_nextPageHintpreserves the active filter set (statusplussearch) and that invalid pagination inputs fail loudly instead of being silently clamped/defaulted.Overall Verdict
Not yet aligned with the repo’s architecture standards. The intent is good, but the current implementation still leaves a shared-tool contract mismatch and a non-fail-loud pagination path, so I would not approve it as-is.
Sent by Cursor Automation: Sunil On Demand Architecture Review
There was a problem hiding this comment.
Stale comment
Not yet aligned with Sunil's architecture standards. I found two correctness issues in the new pagination path:
src/registry/toolsets/sto.ts: the STO preflight overloadssize=20to mean "unspecified", so an explicit publicharness_list(..., size=20)request can never be honored and is rewritten to5. That also sets a precedent of silently rewriting shared-tool inputs instead of failing loudly.src/registry/extractors.ts:_nextPageHintis advertised as the exact follow-up call, but it drops active filters from the current request. In particular, a pagedsearchflow will switch datasets on page 2.Test gap: I couldn't find focused coverage for the public
harness_list(resource_type="security_exemption")path that proves explicitsize=20is preserved or that_nextPageHintcarries forward the active filters.CI note: the PR's current GitHub checks are green, but these two cases still look like behavioral regressions.
Sent by Cursor Automation: Sunil On Demand Architecture Review
There was a problem hiding this comment.
1 important finding:
src/tools/harness-list.ts,src/registry/toolsets/sto.ts,tests/registry/sto-exemptions.test.ts: the publicharness_listpath still defaults omittedsizeto20before STO-specific logic runs. On current HEAD, parsing the registeredharness_listschema for{ resource_type: "security_exemption", filters: { status: "Pending" } }materializes{ page: 0, size: 20, ... }, and the dispatched request goes out withpageSize=20. That means the new STO pagination guidance only holds when callers explicitly overridefilters.size; the runtime does not actually back the advertised first-page size of 5. The added tests miss this live path because they only exercisepreflight/Registry.dispatch()directly, and the existing tool-handler stubs invoke handlers without SDK/Zod validation, so they never see the defaultedharness_listentrypoint. I did not find additional issues beyond this live-path size-default gap.
Sent by Cursor Automation: Sunil On Demand Architecture Review
| } | ||
| }); | ||
|
|
||
| it("leaves size untouched when caller omits it (no silent default)", async () => { |
There was a problem hiding this comment.
This assertion only proves the internal preflight helper path. It doesn't cover the live harness_list contract, where the MCP SDK applies the shared Zod defaults before the handler runs. On current HEAD, harness_list({ resource_type: "security_exemption", filters: { status: "Pending" } }) still materializes size: 20 / page: 0, and the request goes out with pageSize=20. Please add a tool-level regression that goes through the registered harness_list schema/handler (or an actual MCP server call), otherwise this suite misses the remaining public-path bug.
There was a problem hiding this comment.
You're right on the live-path finding — confirmed empirically that with
size: z.number().min(1).max(100).default(20).optional() in
src/tools/harness-list.ts, an omitted size materializes as 20 after Zod
parsing, so the request goes out with pageSize=20. The current STO-side
preflight cannot distinguish "Zod-defaulted 20" from "caller-explicit 20",
so any STO-only attempt to enforce default-5 would either:
(a) silently rewrite size=20 → 5, which violates the shared-tool contract
and is exactly the regression flagged in your earlier review, or
(b) require removing .default(20) from harness-list.ts — a cross-team
platform change touching the shared harness_list schema used by
23 other listable toolsets.
Option (b) is the correct architectural fix but is out of scope for
STO-11498 (STO ticket cannot change shared platform behavior without
platform-owner sign-off and regression testing across all listable
resources).


Description
Fix exemption list pagination & repeated rows
Problem
The MCP exemption listing had three compounding issues:
harness_list's shared input schema defaultssize=20via Zod. The registry appliesdefaultQueryParamsbefore mapping input→queryParams, sosize=20always overrode the STO-specificpageSize=5. Net effect: server always receivedpageSize=20.offset = page × pageSize. When the LLM changedsizebetween calls (e.g. first call size=20, "next 5" → size=5), rows were silently skipped or repeated.compactItemspass was stripping intentional display fields (severity,requested_by, etc.).Fix
STO-scoped where possible; minimal, additive, opt-in infra changes where not.
listop that normalizesinput.size(treat theharness_listschema default20as "unspecified" → 5; clamp to[1, 50]) and defaultspageto 0. Removed the now-deaddefaultQueryParams. Description/filter fields tightened so the LLM keepssizeconstant across a session.itemsinto a_action_id_by_rowlookup, and appends a_nextPageHintstring so the LLM copies the exact next call (samesize,page+1).skipCompact?: booleanon EndpointSpec. When set, the registry tags the result with a non-enumerable__skipCompactmarker (so it never leaks to the user-visible JSON) andharness_listskips its generic compaction. Default behavior for every existing resource is unchanged.Behavior after this PR
size→ server getspageSize=5, page 0 → rows 1–5._nextPageHint→ page=1, size=5 → rows 6–10.size=10, preflight leaves it alone, size stays 10 for subsequent pages.Scope check
skipCompactis a generic, backwards-compatible opt-in mechanism (no other spec sets it today).Verification
pnpm buildclean.pnpm test— 1194/1194 passing.Type of Change
Checklist