Skip to content

fix(monitor): resilient registry enumeration — stop silent truncation of the 66k baseline#34

Merged
Ap6pack merged 1 commit into
mainfrom
claude/project-audit-modernize-lda8id
Jul 17, 2026
Merged

fix(monitor): resilient registry enumeration — stop silent truncation of the 66k baseline#34
Ap6pack merged 1 commit into
mainfrom
claude/project-audit-modernize-lda8id

Conversation

@Ap6pack

@Ap6pack Ap6pack commented Jul 17, 2026

Copy link
Copy Markdown
Owner

The bug

The sweep was scanning only a few hundred to a few thousand skills instead of
the full registry, and had been since 07-07. The intended design — baseline
all skills once (budgeted), then re-enumerate everything each run and re-scan
only new/changed via the diff — was silently broken.

Evidence from the snapshot history on the data branch:

Date Enumerated
07-06 66,544 correct: scanned 4k, deferred 60k as pending
07-07 91 enumeration collapsed
07-08…07-16 395–2,940 erratic, pending=0 every run (falsely "complete")

Root cause (two compounding bugs):

  1. The client retries only connection-level failures. During a ~1,300-page
    listing of 66k skills, one rate-limit/5xx/timeout threw, and
    _enumerate_skills silently breaked and returned the partial list.
  2. build_snapshot treated that partial list as authoritative and dropped
    every previously-known skill not in it
    — so one hiccup wiped the baseline.

The fix

  1. Resilient pagination — retry each failed page (4 attempts, finite
    backoff) before giving up, and return a complete flag. Natural end with
    every page ok → complete; a page still failing after retries → partial
    (logged loudly, run continues).
  2. Baseline protection — on an incomplete enumeration, carry previously-known
    skills forward instead of dropping them. A complete enumeration still allows
    genuine removals. Records enumerated_count / enumeration_complete /
    carried_forward_count on the snapshot for visibility (and the Discord
    summary/logs now surface it).

Tests

New enumeration-resilience coverage: transient-page-retry-then-complete,
persistent-page-failure-marks-incomplete, incomplete-carries-forward-baseline,
complete-enumeration-allows-genuine-removal, empty-listing-preserves-baseline.
Full unit suite: 1445 passing; ruff + mypy clean.

After merge

The next full re-scan should re-enumerate the whole ~66k registry and rebuild
the budgeted baseline (draining pending over successive runs) instead of
scanning a sliver. Coverage will be visible via enumerated_count /
enumeration_complete in each snapshot and the Discord summary.

🤖 Generated with Claude Code


Generated by Claude Code

…y truncates

The registry sweep was scanning only a few hundred to a few thousand skills
instead of the full ~66k, and had been since 07-07. Root cause: the client
retries only connection-level failures, so a single rate-limit/5xx mid-listing
threw, and _enumerate_skills silently broke out of pagination and returned the
partial list. build_snapshot then treated that partial list as authoritative
and dropped every previously-known skill not in it -- one hiccup collapsed the
66k baseline (66,544 on 07-06 -> 91 on 07-07).

Two fixes:

1. Resilient pagination: retry each failed listing page (4 attempts, finite
   backoff) before giving up, and return a completeness flag. Reaching the
   natural end with every page ok -> complete; a page that still fails after
   retries -> partial (does not abort the run).

2. Baseline protection: when enumeration is incomplete, carry previously-known
   skills forward instead of dropping them, so a transient listing failure can
   no longer shrink the baseline. A complete enumeration still allows genuine
   removals. Records enumerated_count / enumeration_complete /
   carried_forward_count on the snapshot for visibility.

Adds enumeration-resilience tests (transient-retry, persistent-partial,
carry-forward, genuine-removal, empty-listing). Full unit suite (1445) passes.

Co-Authored-By: Claude <noreply@anthropic.com>
@Ap6pack
Ap6pack merged commit a821488 into main Jul 17, 2026
5 checks passed
Ap6pack added a commit that referenced this pull request Jul 17, 2026
…runcation (#36)

* fix(monitor): pace registry enumeration to stop throttle truncation

#34 made a truncated enumeration fail safely (honest incomplete flag + baseline
carry-forward), but a verification run showed it still only listed ~3,346 of
~66k skills: the ~1,300-page listing fires as fast as possible and trips the
registry's sustained-listing throttle partway through, at a variable point
(429/940/2,940/3,346 across runs).

Pace the listing to ~2 req/s (matching the registry's observed limit) so it
stays under the throttle, and extend the per-page retry/backoff to outlast a
throttle window. Full enumeration then costs ~11 min, within the run's time box.

Tests zero the pacing/backoff via the autouse fixture so the suite stays fast.
Monitor tests (49) pass; ruff + mypy clean. True coverage is confirmed by the
next run's enumerated_count / enumeration_complete.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(monitor): tunable listing page size to cut enumeration requests

Enumerating the ~66k registry at the hardcoded page_size=50 is ~1,330 listing
requests, the bulk of the throttle exposure. ClawHub has no bulk/export
endpoint (public API is /skills paginated, /search, /skills/{slug}[/file],
rate-limited to 120 req/min), so fewer/larger pages is the main lever.

Add --page-size (default 100, was 50) to 'crawl monitor' and a page_size
workflow dispatch input, so a larger page can be tried without code changes
(the API returns its own max if we request more). At 100/page enumeration
halves to ~660 requests; if the API honors 250, ~270.

Complements the pacing/backoff fix in this branch. yaml + CLI help verified;
monitor tests (49) pass, ruff + mypy clean.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants