Skip to content

[architect] GitHub API plumbing forked 3 ways: lib/request-queue.js (CJS), lib/gh.js (ESM), and 8 hand-rolled token+header sites in fetch-*.js #1232

Description

@kubestellar-hive

Architecture Finding

Type: anti-pattern / duplicated infrastructure
Affected area: scripts/ fetch layer (24 fetch-*.js build-time fetchers)

Three competing implementations of the same GitHub API plumbing:

  1. scripts/lib/request-queue.js (CJS) — githubHeaders, retryWithBackoff, sequentialFetchWithDelay. Adopted by 4 scripts (fetch-contributors, fetch-github-profiles, fetch-github-repos, fetch-portal-contributors).
  2. scripts/lib/gh.js (ESM) — ghFetch, headers with accept: application/vnd.github+json + x-github-api-version. Adopted by 2 scripts (fetch-dora, fetch-ghcr-packages). Factory-scoped per adr/0003.
  3. Hand-rolled inline at 8+ sites: fetch-feeds.js (own token + Link pagination), fetch-pin-state.js (own headers, Accept: application/vnd.github.v3+json, AbortSignal timeout), fetch-hive-live-data.js, fetch-hive-history.js, fetch-factory-stats.js, lib/factory-monthly-metrics.mjs, lib/tap-promotions.mjs, lib/sbom/api.js.

Token acquisition (process.env.GITHUB_TOKEN || process.env.GH_TOKEN) is restated at 13+ sites. Header shape diverges: some set x-github-api-version: 2022-11-28, some set the legacy v3+json accept, most set neither; User-Agent differs per file. Retry/timeout behavior diverges: request-queue users get backoff, gh.js users get throw-on-non-2xx, hand-rolled sites get whatever the author wrote (fetch-feeds has no timeout at all).

Impact

Rate-limit handling, auth failure behavior, and API version pinning are per-script accidents. A token-scope or API-version change requires sweeping a dozen files, and the CJS/ESM split between the two shared libs means neither can absorb the other without conversion work. Silent divergence in failure modes: some fetchers degrade to fallback payloads, others throw, others hang.

Recommendation

Converge on one client module per module system (or convert the scripts layer to ESM and keep only lib/gh.js): single githubToken(), single header builder with one Accept/api-version contract, and one retry/timeout policy. Migrate the hand-rolled sites incrementally — each migration is behavior-neutral and independently reviewable.


Filed by architect agent (ACMM L5 — hold-gated mode)

🐝 Hive Agent: architect | Instance: hosted-projectbluefin-knuckle-gjvq | SHA: unknown

— hive: agent=architect backend=copilot model=kimi-k3 copilot=1.0.78

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/architectFiled or owned by the architect agent.architectureStructural or interface design work.hive/hosted-projectbluefin-knuckle-gjvqRouted by the hosted Project Bluefin Hive deployment.tech-debtAccumulated debt to pay down.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions