Skip to content

Relay resilience: distinguish GitHub rate limits from access denials and retain safe offline semantics #11

Open

Description

@McHersheys

Problem

Relay-linked local work has two different dependencies: Git transport and the relay's GitHub App permission checks. Debouncing git fetch/push does not remove the latter.

At main d008e18, source inspection finds:

  • relay/github.js:126–132 maps every GitHub 401/403/404 to NO_REPO_ACCESS, before checking rate-limit headers. GitHub documents primary and secondary limits returning 403 or 429 (docs).
  • relay/auth.js:242–264 checks writes afresh and caches NO_REPO_ACCESS as a denied read. A rate-limit 403 can therefore become an apparent permission loss, including after the provider recovers.
  • GITHUB_UNAVAILABLE is HTTP 503 in relay/auth-http.js, but falls through to HTTP 400 in src/api-http.js:374–376. The sealed API consequently does not expose that provider failure as the transient 5xx class recognized by the existing optional outbox.

This is a source-derived failure path, not evidence that the hosted relay was historically rate limited. No hosted response headers, deployed revision or provider budget have been established, and no load/stress test is proposed.

Existing offline support, not a request to skip ACKs

relay.outbox: true already provides an opt-in sealed queue on an accepted ordered link (src/relay-outbox.js, docs/api.md); it is off by default. Queued moves are locally visible but can be refused at replay. H10 still specifies offline refusal by default; H21 is draft. A partition cannot also guarantee that a claim has won globally.

Please preserve that distinction and the existing actor/token checks, person-only operations, sequence/nonce binding, move IDs, conflict receipts and lost-ACK recovery. Do not turn all 403s into transient failures, authorize remote writes from a stale read cache, or treat a local queue receipt as a relay commit.

Bounded first increment

  1. Recognize header-evidenced GitHub rate-limit 403s as GITHUB_UNAVAILABLE; keep ordinary 401/403/404 denials unchanged.
  2. Return 503 for that code on the sealed API too; remote authorization still refuses the operation and the relay stores nothing.
  3. Add loopback regressions for primary/secondary header signals, genuine denials, permission-cache recovery, and opted-in outbox replay after provider recovery.
  4. Document remaining offline-claim gates: provisional versus authoritative claims, revocation/expiry boundaries, crash/power-loss durability, bounded backlog/backpressure and idempotent reconciliation. A locally authoritative mode would need an explicit authority/fencing contract, not an ACK bypass.

This is distinct from #8/#9 (SQLite page-cache ACK contention). A compact draft patch/design follows; runtime qualification remains required before adoption.

Activity

  1. added
    bugPullboard doesn't work as documented; open while we look into it
    on Oct 26, 2026
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

    bugPullboard doesn't work as documented; open while we look into it

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions