Skip to content

docs(platform): design forge retry-after error surface (RIG-2255) - #653

Open
rigel-mintaka wants to merge 1 commit into
mainfrom
compass-forge/rig-2255-retry-after-surface
Open

docs(platform): design forge retry-after error surface (RIG-2255)#653
rigel-mintaka wants to merge 1 commit into
mainfrom
compass-forge/rig-2255-retry-after-surface

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Design record for RIG-2255: the forge-call chokepoint's ForgeCallError.retry_after_ms wire field is structurally always 0 because no forge error type carries the rate-limit reset out of the provider client. The chokepoint serves reads and writes alike — mapForgeError maps get_issue/get_pull_request/list_issues the same as the write ops, and the fail-fast gate arms per-request regardless of direction — so a rate-limited read surfaces the same always-0 hint as a write.

Approach

A dedicated *forge.RateLimitError{RetryAfter time.Duration} in go/internal/forge/provider.go that Unwrap()s to ErrBudgetExhausted, replacing the bare sentinel wrap at every emission site. errors.Is(err, ErrBudgetExhausted) keeps matching (the poll driver's skip contract, the server's resource_exhausted arm, and all existing tests are undisturbed); errors.As recovers the hint at mapForgeError. The reset is carried as a time.Duration computed client-side via the injectable clock, so the server conversion to retry_after_ms is clockless clamped arithmetic ([0, math.MaxUint32] ms before the uint32 cast). Covers GitHub + Linear, both the live-response classifier and the fail-fast gate, and both read and write call paths.

Option B (widen StatusError and reroute rate limits through it) rejected on grounded evidence: it breaks the poll driver's sentinel skip/abort classification and misses the dominant carrier (a rate-limited 403/429 never becomes StatusError{429} today).

Review history

Design-critic red-team (pre-freeze): 0 blocking, 0 load-bearing forks for Matt; 1 medium + 3 low folded (the X-Ratelimit-Reset-only-429 dropped-hint edge documented out-of-scope; proto-comment semantic widening; test-site enumeration; count phrasing). Core choices (option A, time.Duration, provenance-agnostic fail-fast hint) all ratified. Review-agent loop all-clear (0 high / 0 med); the read-scope framing fix above lands from Matt's DM.

Scope boundary

Populates the existing retry_after_ms proto field; does not reshape it (confirmed forge-internal with compass-server, the field's lane owner). Design record only — implementation (T1-T5 in the record) is a separate follow-up PR.

Refs RIG-2255
Ledger-impact: adds DL-276 (Comms & tools; forge rate-limit reset hint surface) in this PR; no rows superseded. Numbered DL-276 as the next contiguous block above landed max DL-268 (#664) and the in-flight mergeable blocks DL-269..271 (#645) + DL-272..275 (#662); rebased onto clean main f7b1923e, design-ledger-gate green.
Spec-impact: none

@linear-code

linear-code Bot commented Aug 26, 2026

Copy link
Copy Markdown

RIG-2255

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-forge-rig-2255-retry.compass-eng-docs.pages.dev

Deployed from compass-forge/rig-2255-retry-after-surface at c99eb5c.

Changed pages:

@rigel-mintaka
rigel-mintaka force-pushed the compass-forge/rig-2255-retry-after-surface branch 2 times, most recently from e0916be to dfeee9a Compare August 26, 2026 07:33
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review August 26, 2026 07:33
Carry the rate-limit reset hint on the forge budget-exhausted error surface
so ForgeCallError.retry_after_ms (structurally always 0 today) is populated:
a dedicated forge.RateLimitError{RetryAfter time.Duration} that unwraps to
ErrBudgetExhausted, emitted from both providers' live and fail-fast sites.

Design record only; impl is a follow-up PR. Ledger delta assigned at freeze.

Refs RIG-2255

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the compass-forge/rig-2255-retry-after-surface branch from dfeee9a to c99eb5c Compare August 27, 2026 03:22
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.

1 participant