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 write 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.

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. Covers GitHub + Linear, both the live-response classifier and the fail-fast gate.

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.

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-268 (Comms & tools; forge rate-limit reset hint surface) in this PR; no rows superseded. Numbered DL-268 to clear #634's in-flight DL-264..267 block — a temporary 264-267 gap on this branch fills when #634 lands.
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 dfeee9a.

Changed pages:

@rigel-mintaka
rigel-mintaka force-pushed the compass-forge/rig-2255-retry-after-surface branch from bbacb51 to e0916be Compare August 26, 2026 07:23
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 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
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