Priority: P1
Problem
RateLimiter defaults to allowing a store failure while HTTP middleware exposes a separate failOpen default that only evaluates quota-denial results. Selecting fail-closed middleware can still admit requests during a store outage.
Evidence
packages/ratelimit-core/src/libs/RateLimiter.ts:16-64 converts store failure according to its own failOpen setting; middleware/rateLimitMiddleware.ts:42-81 has a separate option and checks only result.success.
Desired outcome
HTTP rate-limit degraded behavior is one explicit policy rather than two contradictory settings.
Implementation path
- Thread a single degraded-store policy through middleware and limiter or reject conflicting settings.
- Emit a diagnostic for store unavailability.
- Test fail-open and fail-closed HTTP requests through a failing store.
Acceptance criteria
- A fail-closed middleware rejects store outages predictably.
- A fail-open middleware permits them with evidence.
- Configuration cannot silently choose a different policy downstream.
Validation
pnpm --filter @croco/ratelimit-core test
pnpm --filter @croco/transports-http test
Scope boundaries
Does not change quota algorithms or proxy identity policy.
Priority: P1
Problem
RateLimiter defaults to allowing a store failure while HTTP middleware exposes a separate failOpen default that only evaluates quota-denial results. Selecting fail-closed middleware can still admit requests during a store outage.
Evidence
packages/ratelimit-core/src/libs/RateLimiter.ts:16-64converts store failure according to its own failOpen setting;middleware/rateLimitMiddleware.ts:42-81has a separate option and checks onlyresult.success.Desired outcome
HTTP rate-limit degraded behavior is one explicit policy rather than two contradictory settings.
Implementation path
Acceptance criteria
Validation
pnpm --filter @croco/ratelimit-core testpnpm --filter @croco/transports-http testScope boundaries
Does not change quota algorithms or proxy identity policy.