Skip to content

feat: add HTTP response chaos rules - #2317

Draft
pmcelhaney wants to merge 1 commit into
mainfrom
agent/chaos-api-monorepo
Draft

feat: add HTTP response chaos rules#2317
pmcelhaney wants to merge 1 commit into
mainfrom
agent/chaos-api-monorepo

Conversation

@pmcelhaney

Copy link
Copy Markdown
Collaborator

Summary

  • add runtime-owned ChaosRule and ChaosRegistry APIs for HTTP-response fault injection
  • expose one server-level registry through every dispatcher and the live REPL, including multi-API simulators
  • support bounded/probabilistic faults, status, delay, case-insensitive header mutation, body replacement/transformation, and lifecycle controls
  • document the public runtime, REPL, reference, and usage-pattern contracts
  • supersedes feat: add chaos() API for HTTP-layer fault injection with default-on rules #2119 with an implementation based on the monorepo package boundaries

Original Prompt

Add a chaos() API for HTTP-layer fault injection.

Manual acceptance tests

  • From the Live REPL, run chaos("/orders").next(3).status(503) and confirm exactly three matching responses return 503.
  • Add a probabilistic rule, stop and restart it, and confirm skipped or stopped requests do not consume its remaining count.
  • In a multi-API simulator, create one global REPL rule and confirm matching routes in two different API groups are affected.
  • Set and remove the same response header with different casing; confirm the last call wins while Content-Type remains unchanged.
  • Add a delayed response rule, then stop it; confirm normal responses resume without restarting Counterfact.

Tasks

  • Put chaos rule behavior and public exports in @counterfact/runtime.
  • Apply the selected rule after normal dispatcher response processing.
  • Expose a supplied runtime registry through @counterfact/repl without deep imports.
  • Share exactly one registry across every facade runner and REPL session.
  • Add package, reference, feature, and pattern documentation.
  • Add patch changesets for runtime, REPL, and counterfact.

Repository learning check

  • Runtime owns HTTP behavior; REPL only exposes a supplied public runtime contract.
  • The facade owns simulator-level composition and shares one registry across API groups.
  • Existing grouped context/scenario boundaries and positional API compatibility are preserved.
  • Removed historical APIs were not restored: indefinite application is the default, with no always() or timeout().

Verification

  • ./node_modules/.bin/tsc --build packages/runtime/tsconfig.json packages/repl/tsconfig.json packages/counterfact/tsconfig.json --force --pretty false
  • changed-file ESLint (no errors)
  • full Jest run: 65 suites, 933 passing, 1 todo, 127 snapshots
  • node scripts/check-package-boundaries.mjs
  • npm_config_cache=/private/tmp/counterfact-npm-cache node scripts/check-publishable.mjs
  • npm_config_cache=/private/tmp/counterfact-npm-cache npm exec --yes --package=yarn@1.22.22 -- node scripts/test-package-closures.mjs
  • git diff --check

The polling override used for watcher-heavy Jest runs avoids the current macOS sandbox's file-descriptor limit; production watcher configuration is unchanged.

Copilot AI lite review requested due to automatic review settings August 18, 2026 15:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a runtime-owned chaos API for HTTP response fault injection, wires it into the dispatcher pipeline, and exposes a shared registry through the REPL and multi-API Counterfact simulators.

Changes:

  • Add ChaosRule / ChaosRegistry APIs (status/delay/header/body mutations, probability + bounded next() rules).
  • Apply chaos rules after normal dispatcher response processing and expose chaos(pathPrefix?) in the REPL when a server-owned registry is provided.
  • Share exactly one ChaosRegistry across Counterfact API groups; add tests + docs + changeset.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/runtime/test/server/chaos.test.ts New unit/integration coverage for chaos rules, registry selection, and dispatcher integration.
packages/runtime/src/server/dispatcher.ts Applies selected chaos rule (including optional delay) after normal response normalization/validation.
packages/runtime/src/server/chaos.ts Implements ChaosRule and ChaosRegistry for response-layer fault injection.
packages/runtime/src/index.ts Exports chaos public API from @counterfact/runtime.
packages/runtime/README.md Documents runtime usage of ChaosRegistry and key constraints (indefinite by default, Content-Type protected).
packages/repl/test/repl.test.ts Verifies REPL only exposes chaos() when supplied a server-owned registry.
packages/repl/src/repl.ts Adds optional chaos() global + help line when a registry is provided.
packages/repl/README.md Documents how to supply a registry and share it across dispatchers + REPL.
packages/counterfact/test/app.test.ts Ensures a single shared registry is used across groups and REPL rules affect multiple groups.
packages/counterfact/test/api-runner.test.ts Verifies ApiRunner passes a supplied chaos registry through to the dispatcher.
packages/counterfact/src/app.ts Creates one simulator-level ChaosRegistry and injects it into all runners + REPL sessions.
packages/counterfact/src/api-runner.ts Threads optional/shared ChaosRegistry through runner construction into the dispatcher.
packages/counterfact/docs/reference.md Adds Chaos API reference section describing behavior/precedence and constraints.
packages/counterfact/docs/patterns/test-fault-scenarios-with-chaos.md New usage pattern page describing fault-testing workflow via REPL chaos rules.
packages/counterfact/docs/patterns/index.md Links the new chaos pattern page and fixes the patterns listing/table formatting.
packages/counterfact/docs/features/repl.md Documents chaos() usage from the REPL and multi-API implications.
.changeset/calm-chaos-rules.md Patch changeset for runtime, REPL, and counterfact releases.
Suppressed comments (2)

packages/runtime/src/server/chaos.ts:70

  • status(code) accepts any number today (including NaN, Infinity, or values outside the HTTP status range), which can lead to invalid responses and confusing downstream behavior. Consider validating that code is an integer in the 100–599 range and throwing a RangeError when it is not.
  public status(code: number): this {
    this.statusCode = code;
    this.touch();
    return this;
  }

packages/runtime/src/server/chaos.ts:76

  • delay(ms) currently accepts negative, NaN, or infinite values. Negative delays are silently ignored by the dispatcher (> 0 check), which can hide mistakes. Consider validating ms as a finite, non-negative number and throwing a RangeError for invalid inputs.
  public delay(ms: number): this {
    this.delayMilliseconds = ms;
    this.touch();
    return this;
  }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +48 to +52
public next(count = 1): this {
this.remaining = count;
this.touch();
return this;
}
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.

2 participants