Document: loomworks-list-loading-scoping-note-v0_1
Version: v0.1
Status: working draft
Date: 2026-06-27
Author: Claude.ai (scoping role)
Queue item: Companion build queue Item 1 — list-loading (cross-cutting pagination concern)
Two-role note: This chat scopes and drafts. CC runs Step 0 and executes. Nothing here is committed to the record until the Operator authorises.
This note was drafted from the manifest's two precedent entries (Axis 11 conversation pagination, Entry 109; personal-recall wholesale-with-backstop, CR-2026-100). The canonical running queue — loomworks-companion-build-queue-v0_3.md in loomworks-record/current-status/ — is not reachable from this chat; it is not in the project mirror. The mirror also carries a stale manifest (v0.56) and a stale seed (v0.8); the canonical seed is v0.12 and the canonical manifest is higher than v0.56 per current project state.
What this means for this note: the pattern below is grounded in precedent I can read in full and is reliable. The endpoint inventory — which listing endpoints exist and which already paginate — is the thing I cannot close from here. That is exactly what the Step-0 brief (companion document) is for: CC reads Item 1's full queue section and the live engine, and reports the real delta. Do not treat the endpoint list in §4 as authoritative; treat it as the hypothesis Step 0 confirms or corrects.
Item 1 is the cross-cutting pagination concern for unbounded-growth lists across every surface. Not "loading states / skeletons" — that is a sub-item of the same queue entry, a different concern (perceived-latency polish), and is out of scope here.
The lists in scope are the ones that grow without bound as an engagement accumulates:
Lists that are held-type or structurally small (bounded sets that do not grow without bound — e.g. a fixed enumeration, a small per-engagement catalogue) stay wholesale: fetched complete, no paging. The wholesale path is not a lesser version of the paged path; it is the correct path for bounded sets, mirroring the personal-recall precedent.
The pattern is not open for re-litigation. It is the settled composite of the two precedents the queue names. Stated as the conformance target:
total_count always visible. The Operator always sees how large the full set is, paged or not — the personal-recall total_count-surfaced precedent generalised. "You are seeing 50 of 312."has_more-gated control. The load-more control appears only when more exists — "only show what is available" (seed). Absent at the end of the set; never a disabled/greyed control.(created_at, id) cursor. The keyset cursor is the pair, not created_at alone. This is the Axis 11 R2 known limitation resolved: the created_at-only strict-< cursor can skip a turn that shares the boundary timestamp and sorts later by id. The composite cursor is the complete fix and was explicitly recorded as the one engine-side follow-on tail. This item is where that tail gets paid, generalised across listing endpoints.total_count surfaced — the personal-recall shape (limit 500 as a visible backstop, complete set returned, no silent clip).
The conversation-history endpoint (/operator/conversation-history) already carries the read-side of this pattern (before cursor + has_more), and Axis 11 already consumes it on the frontend. The conversation endpoint is the reference implementation. The work of this item is extending the same shape to the room-listing and engagement-listing endpoints — and, where the composite cursor is not yet present even on conversation-history, landing it there too so one cursor shape governs everywhere.
Axis 11 was frontend-only because the conversation endpoint already paged. The room and engagement listings are the open question: if they currently return wholesale, this item carries a real engine delta (adding keyset pagination — limit, composite cursor params, has_more, total_count — to those endpoints), unlike Axis 11.
So the honest shape of this item, before Step 0, is:
has_more, total_count. Each endpoint touched is a read-path change; none writes, derives, or touches provenance (same Memory-read-boundary classification as Axis 11 — a pure read of what already exists).has_more, surfacing total_count. The Axis 11 CenterPane control is the prior art; this generalises it into something reusable rather than CenterPane-specific.The reason Step 0 must run before the CR is drafted: the engine delta is the load-bearing unknown. We do not know which listings already page (zero engine work, frontend-only like Axis 11) and which return wholesale (real engine work). The CR's size, classification, and step plan all depend on that count.
From the stale manifest, two listing endpoints are visible:
GET /engagements — scoped to the caller's memberships (shipped 2026-05-19, engagement-list-scoping-v0_1). The home engagement list. Paging status unknown.GET /operator/conversation-history — already paged (before + has_more); the reference. Composite-cursor status: per Axis 11, was created_at-only at that time; may still be.Not visible from here, to be enumerated by Step 0:
/engagements or another read. Unknown.§4 is deliberately thin because closing it from a stale mirror would be guessing. Step 0 closes it against the live engine.
limit=50 for conversation turns. Default lean: 50 for room/engagement listings too, unless a surface has an obvious different natural page (e.g. a card grid). Confirm or set per-surface at CR time, after Step 0 shows the surfaces.created_at DESC) everywhere unless the surface's purpose dictates otherwise; the composite cursor is order-agnostic. Set per-surface at CR time.None of these block Step 0. They are resolved at CR-drafting time, with Step 0's inventory in hand.
has_more-gated control, no disabled/greyed load-more. Honoured.cursor/has_more/total_count stay in code-translation contexts. Honoured.No apparent conflict with the seed. The one caveat: this note is checked against seed v0.8 (stale mirror); the live seed is v0.12. Step 0 / CR drafting should re-verify against canonical v0.12 before the CR is approved. Flagged, not silent.
The companion Step-0 inspection brief (loomworks-list-loading-step-0-inspection-brief-v0_1) goes to CC. CC reads Item 1's full section in the canonical queue, enumerates the live listing endpoints, reports paging status per endpoint, and returns the real engine delta. The CR is drafted only after Step 0 is Operator-accepted.