# MC #105153 — API write bucket stage E2E rate-limit override

# MC #105153 — Bilko API write bucket 429 stage E2E

## Scope
Fix authenticated `api` rate-limit bucket 429s on stage E2E for sentinel contact create and instant-demo write-protection probes, while preserving production defaults.

## Changes verified on disk
- `apps/api/src/main/kotlin/no/alai/bilko/plugins/RateLimit.kt`
  - Added `apiRateLimitConfig(perMinuteEnv)` parser.
  - `RateLimitName("api")` now uses `API_RATE_LIMIT_PER_MINUTE` with default `100`.
- `apps/api/src/test/kotlin/no/alai/bilko/plugins/RateLimitTest.kt`
  - Added tests for default `100`, stage override `500`, invalid fallback `100`.
- `azure-pipelines.yml`
  - Stage ACA deploy sets `API_RATE_LIMIT_PER_MINUTE=500` for `bilko-api-stage`.
- `.github/workflows/azure-stage.yml`
  - Stage ACA deploy sets `API_RATE_LIMIT_PER_MINUTE=500`.
- `.env.example`
  - Documents `API_RATE_LIMIT_PER_MINUTE`, `AUTH_RATE_LIMIT_PER_MINUTE`, `DEMO_RATE_LIMIT_PER_MINUTE`, `DEMO_RATE_LIMIT_PER_HOUR` defaults.
- `infrastructure/gcp/ENV-MATRIX.md`
  - Documents stage-only `API_RATE_LIMIT_PER_MINUTE=500`; demo/prod default/absent.

## Verification — 2026-07-09T23:07Z
Command run from `apps/api`:

```bash
./gradlew test --tests no.alai.bilko.plugins.RateLimitTest --rerun-tasks
```

Result: `BUILD SUCCESSFUL in 21s`, `7 actionable tasks: 7 executed`.

JUnit XML evidence:

```text
apps/api/build/test-results/test/TEST-no.alai.bilko.plugins.RateLimitTest.xml
<testsuite name="no.alai.bilko.plugins.RateLimitTest" tests="22" skipped="0" failures="0" errors="0" ...>
```

Static presence check:

```bash
grep -n "API_RATE_LIMIT_PER_MINUTE" \
  apps/api/src/main/kotlin/no/alai/bilko/plugins/RateLimit.kt \
  apps/api/src/test/kotlin/no/alai/bilko/plugins/RateLimitTest.kt \
  azure-pipelines.yml .github/workflows/azure-stage.yml \
  infrastructure/gcp/ENV-MATRIX.md .env.example
```

Observed paths/lines:
- `apps/api/src/main/kotlin/no/alai/bilko/plugins/RateLimit.kt:115`
- `apps/api/src/main/kotlin/no/alai/bilko/plugins/RateLimit.kt:125`
- `azure-pipelines.yml:527`
- `.github/workflows/azure-stage.yml:181`
- `infrastructure/gcp/ENV-MATRIX.md:36`
- `.env.example:70`

## Production-safety note
Production default remains unchanged: absent/invalid `API_RATE_LIMIT_PER_MINUTE` resolves to `100`, and only stage deploy config sets `API_RATE_LIMIT_PER_MINUTE=500`.


## P2P pre-verifier
- PASS: mesh-thr-77df628b-c7b4-4c5e-a3ff-1825826bb7f9 / mesh-msg-f642fa23-cb94-476f-af4b-01a63f386be2
- Evidence JSON: /tmp/alai/company-mesh-auto-responder/2026-07-09T23-10-17-743Z-mesh-msg-f1bd06a1-d6a6-4b9d-84b8-e60304ecfc39.json