Skip to content

fix(entries): correct merged-timeline pagination on includeLinkedPersons#64

Merged
arapov merged 1 commit into
masterfrom
fix/merged-timeline-pagination
May 29, 2026
Merged

fix(entries): correct merged-timeline pagination on includeLinkedPersons#64
arapov merged 1 commit into
masterfrom
fix/merged-timeline-pagination

Conversation

@arapov
Copy link
Copy Markdown
Collaborator

@arapov arapov commented May 29, 2026

Summary

Fixes two real pagination bugs in the v1.6.6 list_party_entries fan-out merge (the includeLinkedPersons path):

  1. Under-fetch for page > 1 — only perPage candidates were pulled per linked party, so a second page sliced from too small a pool and could come back short or empty.
  2. False end-of-feed on an exactly-full page 1nextPage was merged.length > start + perPage, which reported undefined when the page filled exactly perPage even though linked parties still had older entries upstream (each party's Link rel=next was discarded). Callers stopped paging early.

Fix: fetch min(page × perPage, 100) candidates per party (mergedTimelineCandidatePerParty), and preserve each party's upstream next-page signal when the requested window fits within the per-party fetch cap (mergedTimelineNextPage). fanOutPartyEntries now returns {entries, nextPage} per party so the signal survives the merge. Very deep pagination on a large multi-person org can still be approximate (documented on the schema). The default (includeLinkedPersons omitted) single-GET path is bit-for-bit unchanged.

Provenance — cherry-picked from #62, churn dropped

The substantive fix comes from codex's #62. I took the entries.ts + entries.test.ts changes and dropped two things that PR also did:

  • v1.6.6 → v1.7.0 text rewrites — the probe scripts are iteration markers (v163–v167), not release versions. The v166 probe verified this behaviour during the v1.6.6-era work; relabeling it "v1.7.0" makes the historical record false.
  • wire-trace-v166.ts → wire-trace-v170.ts rename — renaming only v166 (while v167 keeps its name) breaks the sequence and the NOTES §32 references.

#62 also correctly noted the next release should be a minor bump (new tools) — that's a release-cut decision, deferred to the cut rather than baked into [Unreleased] doc text now.

Closes #62 (cherry-picked clean).

Test plan

  • 536 → 537 tests (+1; fix(entries): preserve merged timeline pagination #62's pagination test, plus the existing v166 coverage)
  • entries.test.ts covers: under-fetch fixed for page 2, exactly-full page 1 preserves nextPage via upstream Link, deep-page approximation documented
  • Typecheck / lint / format:check / build clean
  • Default single-GET path unchanged (the no-includeLinkedPersons canary still passes)
  • HOWTO test count + bundle canary synced (537 / ~168 / ~196 KB)
  • Privacy sweep clean

🤖 Generated with Claude Code

Two off-by-one-class bugs in the v1.6.6 fan-out merge path:

  1. Under-fetch for page > 1 — only `perPage` candidates were pulled
     per linked party, so page 2 sliced from too small a pool and
     could come back short/empty.
  2. False end-of-feed on an exactly-full page 1 — nextPage was
     `merged.length > start + perPage`, which reported undefined when
     the page filled exactly perPage even though linked parties still
     had older entries upstream (the per-party Link rel=next was
     discarded).

Fix: fetch min(page × perPage, 100) candidates per party
(mergedTimelineCandidatePerParty), and preserve each party's upstream
next-page signal when the requested window fits within the per-party
fetch cap (mergedTimelineNextPage). fanOutPartyEntries now returns
{entries, nextPage} per party so the signal is available. Very deep
pagination on a large multi-person org can still be approximate
(documented). Default single-GET path unchanged.

Cherry-picked from the substantive part of codex PR #62, dropping
that PR's v1.6.6→v1.7.0 doc rewrites and the wire-trace-v166→v170
rename — the probe scripts are iteration markers (v163–v167), not
release versions, and renaming only v166 would break the sequence
and the NOTES §32 references. The release-version bump is a
release-cut decision, deferred.

537 tests (+1). Bundle 168.08 KB stdio / 195.95 KB http.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@arapov arapov merged commit 1b3095c into master May 29, 2026
1 check passed
@arapov arapov deleted the fix/merged-timeline-pagination branch May 29, 2026 08:19
arapov added a commit that referenced this pull request May 29, 2026
#67)

Cherry-picked the genuine bits from codex PR #66, dropping that PR's
v1.6.6→v1.7.0 doc rewrites and the wire-trace-v166/v167→v170-* probe
renames (iteration markers, not release versions — rejected the same
way as #62/#64).

Real fixes the audit's docs lane missed:
  - README.md tool table: Tags row now lists delete_tag_definition
    (was added to the catalog but not the README table).
  - src/capsule/cache.ts: header + invalidateByPrefix doc comments now
    name delete_tag_definition as a third tag-mutating tool that drops
    the list_tags cache (accurate — the handler does call
    invalidateByPrefix), and generalize "/tags" → "/<entity>/tags".

Test coverage:
  - tests/cache.test.ts: delete_tag_definition invalidates the cached
    list_tags response.
  - tests/entries.test.ts: a merged-timeline window that CROSSES the
    100-entry ceiling returns the in-ceiling tail and ends the feed
    (complements the #65 boundary test with the partial-window case).

Plus a sharper PAGINATION CAVEAT wording (distinguishes crossing-window
truncation from beyond-ceiling empty) — kept the v1.6.6 provenance.

Closes #66 (cherry-picked clean). 538 → 540 tests.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant