Skip to content

fix(agents): page the whole agent registry, not the first 1000 (#320) - #889

Merged
biwasxyz merged 1 commit into
mainfrom
fix/agent-resolver-page-cap
Jul 23, 2026
Merged

fix(agents): page the whole agent registry, not the first 1000 (#320)#889
biwasxyz merged 1 commit into
mainfrom
fix/agent-resolver-page-cap

Conversation

@biwasxyz

Copy link
Copy Markdown
Contributor

Closes #320.

Root cause

fetchBulkAgents() in src/services/agent-resolver.ts capped its pagination loop at a hardcoded BULK_MAX_PAGES = 10:

const BULK_PAGE_SIZE = 100; // max allowed by aibtc.com
const BULK_MAX_PAGES = 10;  // safety cap: 1000 agents max

for (let page = 0; page < BULK_MAX_PAGES; page++) { ... }

That covers offsets 0–999. The aibtc.com registry now returns pagination.total: 104911 pages. Page 10 was never requested, so every agent past index 999 was unreachable in the batch resolution path and rendered on /agents as a truncated BTC address.

Verification against production

Of the 20 correspondents currently showing an address instead of a name, 9 have an upstream displayName (the other 11 are genuinely unnamed — correct fallback). Every one I traced sits on page 10:

Agent Rank Signals Registry page Upstream displayName
Encrypted Zara 14 239 10 'Encrypted Zara'
Dual Cougar 45 177 10 'Dual Cougar'
Secret Mars 49 175 10 'Secret Mars'
Ionic Anvil 155 103 10 'Ionic Anvil'

This also explains why #320 read as intermittent. Its original March screenshot cited Ionic Anvil and Dual Cougar as the agents displaying correctly. They fell off the end as the registry grew past 1,000 — a boundary crossing, not the race condition the issue hypothesised.

Second-order effect

When the loop exited on the page cap, hasMore was still true, so complete stayed false and the negative-cache write at line 223 was skipped. Those addresses were therefore re-fetched on every correspondents rebuild — 10 sequential registry pages, 15s timeout each, all still failing — re-introducing exactly the cold-rebuild cost #867 set out to remove (see #690).

The fix

The loop now sizes itself from pagination.total on the first page, and still stops on hasMore. The surviving constant is renamed BULK_HARD_PAGE_CEILING and raised to 200 pages, documented as a runaway guard rather than a coverage limit, so registry growth can never silently truncate the fetch again.

Tests

New src/__tests__/agent-resolver-pagination.test.ts covers:

  1. Resolving an agent past index 999 (the truncation boundary)
  2. Both sides of the boundary in one call
  3. Positive caching of a past-boundary name
  4. Page-count exactness — 11 pages for 1049 agents, not a walk to the ceiling
  5. A genuinely absent address is still negative-cached on a complete fetch
  6. No negative-caching when the fetch is incomplete

5 of the 6 fail against the pre-fix resolver (verified by reverting). Full suite green: 476 passed, 48 files. tsc --noEmit and biome lint clean on both changed files.

Deploy note

This is served by the news-singleton DO path via /api/correspondents and /api/init. Per prior experience the DO keep-alive can block eviction onto new code — a manual wrangler deploy may be needed for the change to take effect, and existing negative-cache entries expire within 30 minutes.

`fetchBulkAgents()` capped its pagination loop at a hardcoded
`BULK_MAX_PAGES = 10` (10 x 100 = offsets 0..999). The aibtc.com registry
now holds 1049 agents, so page 10 was never requested and every agent past
index 999 became permanently unresolvable in the batch path — rendering on
/agents as a truncated BTC address despite the registry holding a
displayName for them.

Verified against production: of the 20 correspondents showing an address
instead of a name, 9 have an upstream displayName, and every one sampled
sits on page 10:

  Encrypted Zara  rank  14, 239 signals
  Dual Cougar     rank  45, 177 signals
  Secret Mars     rank  49, 175 signals
  Ionic Anvil     rank 155, 103 signals

This also explains why the issue read as intermittent: #320's original
screenshot cited Ionic Anvil and Dual Cougar as displaying *correctly* in
March. They fell off the end as the registry grew past 1000 — a boundary
crossing, not a race.

Second-order effect: when the loop exits on the page cap, `complete` stays
false, so the negative-cache write is skipped. Those addresses were
re-fetched on every correspondents rebuild — 10 sequential registry pages
per rebuild, all still failing — re-introducing the cold-rebuild cost that
#867 set out to remove (#690).

The loop now sizes itself from `pagination.total` on the first page and
still stops on `hasMore`. The remaining constant is renamed to
BULK_HARD_PAGE_CEILING and raised to 200 pages, documented as a runaway
guard rather than a coverage limit, so registry growth can never silently
truncate the fetch again.

Adds a regression test covering the boundary, both sides of it in one call,
positive caching past the boundary, page-count exactness, and that a
genuinely-absent address is still negative-cached only on a complete fetch.
5 of the 6 fail against the pre-fix resolver. Full suite green (476).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
agent-news 03ae77a Jul 23 2026, 04:59 AM

@github-actions

Copy link
Copy Markdown
Contributor

Preview deployed: https://agent-news-staging.hosting-962.workers.dev

This preview uses sample data — beats, signals, and streaks are seeded automatically.

@biwasxyz
biwasxyz merged commit c919208 into main Jul 23, 2026
7 checks passed
@biwasxyz
biwasxyz deleted the fix/agent-resolver-page-cap branch July 23, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agents page: agent name sometimes shows truncated BTC address instead of name

1 participant