feat: chaos for proxy mode (drop, disconnect, malformed)#122
Merged
Conversation
12abf48 to
696522a
Compare
commit: |
0082dc3 to
65ffff8
Compare
f4b4ba1 to
1c67ed0
Compare
5 tasks
54a524d to
d66e3bf
Compare
Chaos (drop, disconnect, malformed) now applies in proxy mode. Previously chaos was skipped for proxied requests. - Pre-flight drop/disconnect pre-empt upstream (nothing is contacted) - Post-response malformed proxies to upstream, captures the response, replaces the body with invalid JSON before relay - Chaos is rolled once per request, after fixture match, with resolved config (headers > fixture.chaos > server-level) - SSE bypass: when the hook can't mutate a streamed response, chaos is skipped and an onHookBypassed callback fires - CORS allow list includes chaos and test-id custom headers - Chaos source label is now explicit (fixture vs proxy) across all applyChaos call sites
Thread applyChaos through all 12 provider handlers with conditional source label (fixture ? "fixture" : "proxy"). Add chaos to handleVideoStatus for completeness.
- proxy-only: pre-flight drop/disconnect, post-response malformed, SSE bypass, proxy failure interaction - chaos-fixture-mode: fixture-mode pre-flight chaos, single roll, journal recording, video status chaos drop - metrics: chaos counter carries source=proxy label - recorder: pin binary-safe hook contract, proxy failure path - server: CORS preflight includes chaos control headers
Document proxy mode behavior (drop/disconnect skip upstream, malformed proxies then corrupts), SSE bypass, sequential rate semantics, journal source field, Prometheus metrics, and per-request header API. Add CHANGELOG entry for chaos-in-proxy-mode feature.
d66e3bf to
4535798
Compare
jpr5
added a commit
that referenced
this pull request
Apr 23, 2026
## Summary Addresses all bucket (c) and (d) items from PR #122's 7-agent CR, plus correctness issues discovered during this PR's own iterative CR process (6 rounds, 4 fix cycles). ### Server core - `readBody` 10MB size limit (DoS surface closed) - Control API: error detail in responses, one-shot race fix (synchronous splice), fixtures_loaded gauge updates on mutations - `normalizeCompatPath` magic number replaced with readable expression - `source` field ("fixture" | "proxy") added to JournalEntry type ### Recorder correctness - Crash hardening: `headersSent` guards, `clientDisconnected` tracking, encoding_format logging - Content+toolCalls: preserve both (previously dropped content) - Cohere v2 native detection branch in `buildFixtureResponse` - Tool-call IDs preserved from 5 provider formats - Reasoning/thinking extracted from 4 provider formats (including tool-call-only) - Multi-block text: `filter+join` instead of `find` (Anthropic/Gemini/Bedrock) - Thinking-only Anthropic responses handled (not error fixture) - Empty-content responses recorded correctly (not error fixture) - Ollama `/api/generate` format detection - Streaming collapse reasoning propagated ### Provider handlers - **Bedrock/Converse**: ContentWithToolCallsResponse guards, ResponseOverrides wired into all builders + streaming, Converse-wrapped stream format (matches collapse parser), `text_delta` type field, Converse error envelope, webSearches warnings - **Cohere v2**: reasoning in all builders + streaming, webSearches warnings, response_format forwarding, assistant tool_calls preservation, full ResponseOverrides (finish_reason, usage, id) - **Ollama**: ContentWithToolCallsResponse, default stream:true, field validation - **Gemini**: tool_call_id collision fix (shared callCounter), thought-part filtering - **All**: journal source field on proxy paths, Azure embedding routing ### Competitive matrix pipeline - `computeChanges` matches actual HTML structure (span class="no") - `applyChanges` regex matches actual td>span structure - `updateProviderCounts` scoped to competitor column (not global) - `extractFeatures` tightened keyword patterns - Added mokksy/ai-mocks competitor ### CI + framework - `--auto` instead of `--admin` on fix-drift merge - Slack secrets via env vars across 5 workflows - Script injection prevention in notify-pr.yml (env vars + jq) - Portable `grep -oE`, SLACK_WEBHOOK guards - Router: RegExp `g`-flag `lastIndex` reset - Jest/Vitest: save/restore pre-existing env vars, loadFixtures warnings ## Test plan - [ ] 2573/2573 tests passing (69 test files) - [ ] TSC clean - [ ] Prettier + ESLint clean - [ ] 0 merge conflicts with main - [ ] 6 CR rounds converged (R1-R4 on original, R1-R6 on additions) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Chaos (drop, disconnect, malformed) now applies in proxy mode. Previously chaos was skipped for proxied requests, making them unrealistically reliable.
What it does
aimock_chaos_bypassed_totalmetric fires.aimock_chaos_triggered_totaland journal entries carrysource: "fixture" | "proxy"to distinguish where chaos fired.Access-Control-Allow-Headersincludes chaos control headers andX-Test-Idfor browser-based test harnesses.handleVideoStatus(GET/v1/videos/:id) now evaluates chaos, consistent with all other handlers.Design highlights
applyChaossplit into roll+dispatch (applyChaosAction) so callers that pre-roll can't re-roll by accident.proxyAndRecordreturns"not_configured" | "relayed" | "handled_by_hook".JournalEntry.response.sourcedisambiguates null-fixture entries.fixture ? "fixture" : "proxy") across all 15+ call sites.Scope
In: malformed / drop / disconnect for proxy mode, non-streaming.
Deferred:
status_override,truncate, streaming (SSE/NDJSON) mutation.Test plan
source="fixture"vssource="proxy"on chaos counterbeforeWriteResponsereceives raw upstream bytes