[GH-ISSUE #60] Add deterministic loopback HTTP and WebSocket replay #46

Closed
opened 2026-10-15 18:20:27 +00:00 by bsakaguchi · 4 comments
Owner

Originally created by @morluto on GitHub (Jul 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/60

Problem

Many CLI state machines depend on callbacks, HTTP APIs, WebSocket messages, reconnects, and timing that unit fixtures cannot reproduce.

Outcome

Provide declarative loopback-only HTTP and WebSocket replay servers owned by a process-capture scenario.

Scope

  • Route/method/header/body matchers with bounds.
  • Scripted responses, delays, disconnects, reconnects, and ordered WebSocket frames.
  • Dynamic loopback ports injected through declared environment variables.
  • Request/response/frame timelines with normalized ports and relative time.
  • Secret/header/body redaction.
  • Typed unmatched-request and script-exhaustion results.

Safety

Bind only loopback interfaces. Deny proxying and external network by default. Bound bodies, frames, connections, duration, and logs. Never persist authorization or cookie values.

Acceptance criteria

Fixtures prove callbacks, redirects, retries, reconnects, malformed frames, timeouts, redaction, cancellation, and cleanup. Replays are deterministic under normalized timing.

Dependencies

Parent: #48. Requires scenario contracts and Evidence v2 behavioral locations.

Non-goals

General MITM, certificate installation, production traffic capture, or internet proxying.

Stateful replay-machine expansion

Static response queues cannot model protocols whose next valid response depends on authentication, prior requests, negotiated IDs, reconnect state, or acknowledged sequence numbers. Add a finite declarative replay state machine.

Contract

A replay machine declares:

  • finite named states and one initial state;
  • bounded HTTP and WebSocket matchers;
  • guards over previously captured, schema-parsed stable variables;
  • response, delay, disconnect, reconnect, and server-push actions;
  • bounded variable extraction from paths, headers, JSON bodies, or frames;
  • explicit transitions and terminal states;
  • per-route, per-state, connection, message, byte, duration, and transition limits;
  • deterministic tie-breaking when multiple transitions match.

No arbitrary JavaScript callbacks or general expression evaluation belong in the portable contract.

Correctness

  • Validate reachability, ambiguity, cycles without finite bounds, missing terminal behavior, invalid captures, secret retention, and conflicting transitions before launch.
  • Preserve every state, matcher, capture, action, and transition in the replay-plan digest.
  • Classify unmatched request, invalid state, guard failure, exhausted transition, unexpected reconnect, and target exit separately.
  • Captured secrets become stable aliases and cannot be used in exported plaintext.
  • A replay run records the full state-transition timeline and links protocol events to triggering transitions.

Paired comparison

Authority and candidate may use separate server instances but must share the same canonical replay machine. Compare their transition traces as well as wire events. A candidate that reaches the same final HTTP status through the wrong transition sequence is different.

Acceptance fixture

Model a login callback, token-bearing API request, WebSocket join with server-assigned reference, ordered acknowledgement, forced disconnect, reconnect, replayed subscription, and terminal response. Vary ports and timing while preserving identical transition traces; detect a candidate that skips authentication, sends the wrong acknowledgement, or reconnects from the wrong state.

Originally created by @morluto on GitHub (Jul 12, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/60 ## Problem Many CLI state machines depend on callbacks, HTTP APIs, WebSocket messages, reconnects, and timing that unit fixtures cannot reproduce. ## Outcome Provide declarative loopback-only HTTP and WebSocket replay servers owned by a process-capture scenario. ## Scope - Route/method/header/body matchers with bounds. - Scripted responses, delays, disconnects, reconnects, and ordered WebSocket frames. - Dynamic loopback ports injected through declared environment variables. - Request/response/frame timelines with normalized ports and relative time. - Secret/header/body redaction. - Typed unmatched-request and script-exhaustion results. ## Safety Bind only loopback interfaces. Deny proxying and external network by default. Bound bodies, frames, connections, duration, and logs. Never persist authorization or cookie values. ## Acceptance criteria Fixtures prove callbacks, redirects, retries, reconnects, malformed frames, timeouts, redaction, cancellation, and cleanup. Replays are deterministic under normalized timing. ## Dependencies Parent: #48. Requires scenario contracts and Evidence v2 behavioral locations. ## Non-goals General MITM, certificate installation, production traffic capture, or internet proxying. ## Stateful replay-machine expansion Static response queues cannot model protocols whose next valid response depends on authentication, prior requests, negotiated IDs, reconnect state, or acknowledged sequence numbers. Add a finite declarative replay state machine. ### Contract A replay machine declares: - finite named states and one initial state; - bounded HTTP and WebSocket matchers; - guards over previously captured, schema-parsed stable variables; - response, delay, disconnect, reconnect, and server-push actions; - bounded variable extraction from paths, headers, JSON bodies, or frames; - explicit transitions and terminal states; - per-route, per-state, connection, message, byte, duration, and transition limits; - deterministic tie-breaking when multiple transitions match. No arbitrary JavaScript callbacks or general expression evaluation belong in the portable contract. ### Correctness - Validate reachability, ambiguity, cycles without finite bounds, missing terminal behavior, invalid captures, secret retention, and conflicting transitions before launch. - Preserve every state, matcher, capture, action, and transition in the replay-plan digest. - Classify unmatched request, invalid state, guard failure, exhausted transition, unexpected reconnect, and target exit separately. - Captured secrets become stable aliases and cannot be used in exported plaintext. - A replay run records the full state-transition timeline and links protocol events to triggering transitions. ### Paired comparison Authority and candidate may use separate server instances but must share the same canonical replay machine. Compare their transition traces as well as wire events. A candidate that reaches the same final HTTP status through the wrong transition sequence is different. ### Acceptance fixture Model a login callback, token-bearing API request, WebSocket join with server-assigned reference, ordered acknowledgement, forced disconnect, reconnect, replayed subscription, and terminal response. Vary ports and timing while preserving identical transition traces; detect a candidate that skips authentication, sends the wrong acknowledgement, or reconnects from the wrong state.
Author
Owner

@morluto commented on GitHub (Jul 17, 2026):

Current main ships bounded static loopback HTTP/WebSocket replay and tests. The expanded finite-state-machine scope remains open: named states, guards and captures, reachability/ambiguity validation, transition traces, paired instances, and the login/reconnect oracle. This is the foundation for the expanded #57 workflow and #61 paired experiments.

<!-- gh-comment-id:5001548654 --> @morluto commented on GitHub (Jul 17, 2026): Current main ships bounded static loopback HTTP/WebSocket replay and tests. The expanded finite-state-machine scope remains open: named states, guards and captures, reachability/ambiguity validation, transition traces, paired instances, and the login/reconnect oracle. This is the foundation for the expanded #57 workflow and #61 paired experiments.
Author
Owner

@morluto commented on GitHub (Jul 17, 2026):

Current-main audit: deterministic loopback HTTP and WebSocket queue replay on literal loopback, schema support, and adapter tests are delivered. Remaining scope is the finite-state replay machine: named states, guards and captures, variable extraction, transitions, terminal states, and a login/reconnect oracle. This issue remains open with that reduced scope.

<!-- gh-comment-id:5002759745 --> @morluto commented on GitHub (Jul 17, 2026): Current-main audit: deterministic loopback HTTP and WebSocket queue replay on literal loopback, schema support, and adapter tests are delivered. Remaining scope is the finite-state replay machine: named states, guards and captures, variable extraction, transitions, terminal states, and a login/reconnect oracle. This issue remains open with that reduced scope.
Author
Owner

@morluto commented on GitHub (Jul 20, 2026):

Split into focused child issues:

These replace the broad remaining scope in this issue. Closing this parent can happen once all children are closed.

<!-- gh-comment-id:5023381460 --> @morluto commented on GitHub (Jul 20, 2026): Split into focused child issues: - [ ] #334 - [ ] #335 These replace the broad remaining scope in this issue. Closing this parent can happen once all children are closed.
Author
Owner

@morluto commented on GitHub (Jul 22, 2026):

Completed by the shipped static loopback replay implementation plus the finite-state replay work in #334 and direct CLI/MCP runner in #335. Both focused child issues are closed, satisfying the parent close condition recorded above.

<!-- gh-comment-id:5051690624 --> @morluto commented on GitHub (Jul 22, 2026): Completed by the shipped static loopback replay implementation plus the finite-state replay work in #334 and direct CLI/MCP runner in #335. Both focused child issues are closed, satisfying the parent close condition recorded above.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#46
No description provided.