Problem
pageview.h is the one paging window and truncation vocabulary, and the high-cardinality CLI
row-listing verbs use it — shown= / total= / capped= / has_more= / next_offset=, fully resumable.
Derivation: pageWindow( is called from 25 source files / 68 call sites outside its own definition
header (rg -c 'pageWindow\(' src | grep -v '^src/pageview.h:'; files and call sites are one-command
countable, so that is the figure stated rather than an approximate verb count).
The MCP task-lens verbs (for, explore) do not. They cut by byte/token budget mid-stream
(handoff.h:291,386 drops heuristic rows tail-first; verbs_for.h:333-345 cuts at the adaptiveCut
relevance cliff; packtask.h:1690 emits bodies grouped by FILE, stopping on a BYTE budget). They
expose capped="1" but no continuation handle, so an agent that overflows the budget cannot fetch the
remainder without inventing a follow-up call it was never handed. This is the "complete-last-page" gap
pageview.h rule 4/H8 already names for row verbs, still open on the task-lens verbs.
Proposed direction — no new vocabulary
Reuse pageWindow(total, limit, offset) (pageview.h:129) over each verb's ranked candidate set, and
reuse the existing bounded limit/offset argument path (mcpverbs.h:327-333) — only the
advertisement of those two arguments on for/explore is new. The continuation is a CANDIDATE offset
(into the ranked order total= already counts), never a byte offset — bodies are byte-trimmed and
file-grouped, so a byte cursor is meaningless. Page k = pageWindow(candidateTotal, limit, offset)
→ the existing byte packer over that slice → the existing pageDisclosure quintet. Additive:
arguments only, no new verb, no new attribute, no new parser.
Out of scope, deliberately: batch (an offset on its 16-sub-query envelope is ill-defined; a
paginating sub-query should call its verb directly) and fixed small blocks (situ.h records why an
offset on a fixed block dropped rows silently — the fix there was deleting the cap, not paging it).
The one decision I'd like maintainer input on
adaptiveCut computes a relevance cliff over the candidate set. How should it compose with paging?
Proposed: compute the cliff ONCE over the full ranked candidate set. Page 1 = the above-cliff tier
(byte-identical for non-paginating callers — that stays the regression floor). Continuation pages serve
below-cliff candidates in raw rank order, carrying their own disclosed set marker (e.g.
tier="below-cliff") so a consumer never reads cliff-rejected content as relevant. total= counts the
full set once; the cliff is a boundary label within it.
Alternative (named, not recommended): re-run adaptiveCut per page. Rejected because it fractures
total= (a different implied denominator per page) and re-opens the "two dialects reporting different
sets under one count" defect class packtask.h:1690 already paid to close.
Blessing or overturning this is the gate to the upstream PR.
Status
A gate-first PoC is in progress on our fork (branch + CI, not our main): arms written first into the
existing gates — truncvocabcheck (paged root carries the full quintet), listingpagingcheck
(offset=limit continuation seam, no gap/overlap), handoffcheck (within-page byte trim keeps rule-5
disclosure), budgetpolicycheck (per-page budget holds), packtaskcheck (below-cliff pages carry
their own marker), adaptivecutshapecheck (cliff invariance) — each shown red on a planted defect
before code. The arm asserting cliff invariance encodes the proposed answer above and will be rewritten
if maintainers pick the alternative; nothing assumes its own open question. Measured evidence will be
linked here when the branch's CI is green. Same discipline as #291.
Problem
pageview.his the one paging window and truncation vocabulary, and the high-cardinality CLIrow-listing verbs use it —
shown= / total= / capped= / has_more= / next_offset=, fully resumable.Derivation:
pageWindow(is called from 25 source files / 68 call sites outside its own definitionheader (
rg -c 'pageWindow\(' src | grep -v '^src/pageview.h:'; files and call sites are one-commandcountable, so that is the figure stated rather than an approximate verb count).
The MCP task-lens verbs (
for,explore) do not. They cut by byte/token budget mid-stream(
handoff.h:291,386drops heuristic rows tail-first;verbs_for.h:333-345cuts at theadaptiveCutrelevance cliff;
packtask.h:1690emits bodies grouped by FILE, stopping on a BYTE budget). Theyexpose
capped="1"but no continuation handle, so an agent that overflows the budget cannot fetch theremainder without inventing a follow-up call it was never handed. This is the "complete-last-page" gap
pageview.hrule 4/H8 already names for row verbs, still open on the task-lens verbs.Proposed direction — no new vocabulary
Reuse
pageWindow(total, limit, offset)(pageview.h:129) over each verb's ranked candidate set, andreuse the existing bounded
limit/offsetargument path (mcpverbs.h:327-333) — only theadvertisement of those two arguments on
for/exploreis new. The continuation is a CANDIDATE offset(into the ranked order
total=already counts), never a byte offset — bodies are byte-trimmed andfile-grouped, so a byte cursor is meaningless. Page k =
pageWindow(candidateTotal, limit, offset)→ the existing byte packer over that slice → the existing
pageDisclosurequintet. Additive:arguments only, no new verb, no new attribute, no new parser.
Out of scope, deliberately:
batch(an offset on its 16-sub-query envelope is ill-defined; apaginating sub-query should call its verb directly) and fixed small blocks (
situ.hrecords why anoffset on a fixed block dropped rows silently — the fix there was deleting the cap, not paging it).
The one decision I'd like maintainer input on
adaptiveCutcomputes a relevance cliff over the candidate set. How should it compose with paging?Proposed: compute the cliff ONCE over the full ranked candidate set. Page 1 = the above-cliff tier
(byte-identical for non-paginating callers — that stays the regression floor). Continuation pages serve
below-cliff candidates in raw rank order, carrying their own disclosed set marker (e.g.
tier="below-cliff") so a consumer never reads cliff-rejected content as relevant.total=counts thefull set once; the cliff is a boundary label within it.
Alternative (named, not recommended): re-run
adaptiveCutper page. Rejected because it fracturestotal=(a different implied denominator per page) and re-opens the "two dialects reporting differentsets under one count" defect class
packtask.h:1690already paid to close.Blessing or overturning this is the gate to the upstream PR.
Status
A gate-first PoC is in progress on our fork (branch + CI, not our
main): arms written first into theexisting gates —
truncvocabcheck(paged root carries the full quintet),listingpagingcheck(offset=limit continuation seam, no gap/overlap),
handoffcheck(within-page byte trim keeps rule-5disclosure),
budgetpolicycheck(per-page budget holds),packtaskcheck(below-cliff pages carrytheir own marker),
adaptivecutshapecheck(cliff invariance) — each shown red on a planted defectbefore code. The arm asserting cliff invariance encodes the proposed answer above and will be rewritten
if maintainers pick the alternative; nothing assumes its own open question. Measured evidence will be
linked here when the branch's CI is green. Same discipline as #291.