Commit 5299f29
fix(telemetry): classify 5xx + rate-limit errors; harden DoS test thresholds
Two follow-ups from the v1.4.0 pre-merge ritual, both surfaced as
[KNOWN GAP] tests in earlier rounds. Neither blocks the merge; both
strengthen the test suite and improve telemetry diagnostics.
## (1) classifyError ERROR_PATTERNS coverage
Round 2 fuzz testing pinned that real provider errors like
"APIError: Service unavailable (503)" and "Rate limit exceeded.
Retry after 60s" classified as `"unknown"` because ERROR_PATTERNS
only matched the prefixed forms ("status code: 5", "http 429").
That defeated the diagnostic value of `agent_outcome.error_class`
for two of the most common provider failure modes.
Adds these phrases to the existing `http_error` class so they
classify into the right bucket:
"service unavailable", "rate limit", "rate_limit",
"retry after", "too many requests", "503", "502", "504"
Why `http_error` and not a new `rate_limit` class: the upstream
event schema uses `http_error` for any non-2xx HTTP failure;
rate-limit responses ARE HTTP 429s, just stated in different
prose. Keeping the same bucket avoids fragmenting telemetry
dashboards.
Tests:
- v140-merge-fuzz.test.ts: replace the 2 `[KNOWN GAP]` tests
with positive assertions:
- "APIError 503 classifies as 'http_error' (Service unavailable)"
- "rate-limit error classifies as 'http_error' (Retry after)"
## (2) DoS test threshold hardening
Round 3 chaos tests asserted regex DoS resistance with fixed
`<100ms` wall-clock thresholds. CI runners under load can flake
on absolute thresholds (slow scheduling, contended I/O, etc.),
even though the actual runtime is fine relative to a baseline.
Replaces fixed thresholds with a relative-budget approach:
- Take the min of 5 baseline runs on a trivial input (filters
scheduler jitter, 1ms floor).
- Run a single warmup invocation before the timed adversarial
call (so JIT-cold doesn't penalize first-run).
- Adversarial input must complete within `50 × baseline`.
Why 50× and not the original implicit 100ms-on-a-fast-runner
(maybe ~200×): catastrophic backtracking on these regexes
would be 1000×+ baseline, so 50× is a generous yet still-strict
budget. Real measurements stayed within ~3× baseline locally.
Tests still pass 5/5 runs locally. The new code prints a
descriptive error message ("X took Yms (baseline Zms × 50 budget
= Wms)") so a future regression has a clear diagnostic.
Combined verification:
- All 4 telemetry/test/upstream suites pass: 87 tests, 3593
assertions, 0 fail.
- Chaos suite alone: 24/24 pass × 5 consecutive runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 0a9a67d commit 5299f29
3 files changed
Lines changed: 68 additions & 24 deletions
File tree
- packages/opencode
- src/altimate/telemetry
- test/upstream
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
925 | 925 | | |
926 | 926 | | |
927 | 927 | | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
928 | 939 | | |
929 | 940 | | |
930 | 941 | | |
| |||
Lines changed: 47 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
29 | 39 | | |
30 | | - | |
31 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
32 | 58 | | |
33 | 59 | | |
34 | | - | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
35 | 73 | | |
36 | 74 | | |
37 | | - | |
| 75 | + | |
38 | 76 | | |
39 | | - | |
40 | | - | |
41 | | - | |
| 77 | + | |
42 | 78 | | |
43 | 79 | | |
44 | | - | |
| 80 | + | |
45 | 81 | | |
46 | | - | |
47 | | - | |
48 | | - | |
| 82 | + | |
49 | 83 | | |
50 | 84 | | |
51 | | - | |
| 85 | + | |
52 | 86 | | |
53 | | - | |
54 | | - | |
55 | | - | |
| 87 | + | |
56 | 88 | | |
57 | 89 | | |
58 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
232 | 232 | | |
233 | 233 | | |
234 | 234 | | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
241 | 242 | | |
242 | 243 | | |
243 | 244 | | |
244 | 245 | | |
245 | 246 | | |
246 | 247 | | |
247 | 248 | | |
248 | | - | |
| 249 | + | |
249 | 250 | | |
250 | 251 | | |
251 | 252 | | |
252 | | - | |
| 253 | + | |
253 | 254 | | |
254 | 255 | | |
255 | 256 | | |
256 | 257 | | |
257 | 258 | | |
258 | 259 | | |
259 | 260 | | |
260 | | - | |
| 261 | + | |
261 | 262 | | |
262 | 263 | | |
0 commit comments