Skip to content

refactor: route all state mutations through process() via system signals#130

Merged
teng-lin merged 2 commits intomainfrom
investigate-e2e
Feb 24, 2026
Merged

refactor: route all state mutations through process() via system signals#130
teng-lin merged 2 commits intomainfrom
investigate-e2e

Conversation

@teng-lin
Copy link
Copy Markdown
Owner

Summary

Fix architecture principle violations #1, #3, #4, #7 by routing all state mutations through SessionRuntime.process() and the pure reducer.

Test plan

  • All 2902 unit + integration tests pass
  • TypeScript typecheck passes
  • Biome formatting check passes
  • No external callers to private transitionLifecycle()
  • BackendConnector no longer calls broadcaster.broadcast() or emitEvent() directly for scoped cases
  • ConsumerGateway no longer emits backend:relaunch_needed directly

🤖 Generated with Claude Code

Fix architecture principle violations #1, #3, #4, #7:

- Fix #1: Remove dual lifecycle mutation by deleting applyLifecycleFromBackendMessage()
  which was redundant with reduceLifecycle()

- Fix #3: Make transitionLifecycle() private. Add SESSION_CLOSING system signal and
  route coordinator's direct calls through process()

- Fix #7: Route ConsumerGateway's backend:relaunch_needed emission through the
  runtime as BACKEND_RELAUNCH_NEEDED system signal instead of emitting directly

- Fix #4: Route BackendConnector's inline broadcasts and event emissions through
  the runtime via routeSystemSignal callback:
  - Part A: Connect/disconnect lifecycle (cli_connected, backend:connected, etc.)
  - Part B: Slash passthrough results/errors (slash_command_result, slash_command_error)

This enforces the core design principle that all state mutations flow through
SessionRuntime.process(), which dispatches to the pure reducer and executes effects.
All 2902 tests pass, typecheck clean.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @teng-lin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the application's state management by centralizing all state mutations through a single SessionRuntime.process() method and a pure reducer. This change addresses several architectural principle violations, leading to a more robust, predictable, and maintainable system. By routing various events and lifecycle transitions as explicit system signals, the PR establishes a clearer separation of concerns and simplifies the flow of data and control within the session management logic.

Highlights

  • Centralized State Mutations: All state mutations are now routed through SessionRuntime.process() and a pure reducer, enforcing a single, predictable flow for state changes.
  • Lifecycle Management Refactor: The transitionLifecycle() method has been made private, and its calls are replaced by system signals processed through the runtime, eliminating dual lifecycle mutation paths.
  • System Signal Integration for BackendConnector: Backend connection/disconnection events and slash command passthrough results/errors are now communicated via system signals instead of direct broadcaster.broadcast() or emitEvent() calls, centralizing event handling.
  • ConsumerGateway Relaunch Signal: The backend:relaunch_needed signal from ConsumerGateway is now routed through the session runtime's process method, aligning with the new centralized signal handling.
  • New System Signal Types: Introduced new system signal kinds, including BACKEND_RELAUNCH_NEEDED, SESSION_CLOSING, SLASH_PASSTHROUGH_RESULT, and SLASH_PASSTHROUGH_ERROR, to support the refactored state management.
Changelog
  • src/core/backend/backend-connector.adapter-selection.test.ts
    • Updated mock dependencies to include routeSystemSignal.
  • src/core/backend/backend-connector.failure-injection.test.ts
    • Updated test setup to provide routeSystemSignal to the connector.
    • Replaced assertions for emitEvent and broadcaster.broadcast with routeSystemSignal for backend disconnection.
    • Replaced assertions for broadcaster.broadcast and emitEvent with routeSystemSignal for slash command errors.
  • src/core/backend/backend-connector.lifecycle.test.ts
    • Updated createDeps function to include routeSystemSignal.
    • Replaced broadcaster.broadcast and emitEvent assertions with routeSystemSignal for backend connection.
    • Replaced broadcaster.broadcast assertion with routeSystemSignal for slash command results.
    • Removed emitEvent assertion for backend disconnection.
    • Replaced broadcaster.broadcast assertions with routeSystemSignal for various slash command results and errors.
  • src/core/backend/backend-connector.test.ts
    • Updated createDeps function to include routeSystemSignal.
  • src/core/backend/backend-connector.ts
    • Imported SystemSignal type.
    • Added routeSystemSignal to BackendConnectorDeps interface.
    • Added routeSystemSignal as a private member to BackendConnector class.
    • Initialized routeSystemSignal in the constructor.
    • Replaced direct broadcaster.broadcast and emitEvent calls with routeSystemSignal for slash command errors.
    • Replaced direct broadcaster.broadcast call with routeSystemSignal for slash command results.
    • Removed emitEvent call for slash_command:executed.
    • Replaced direct broadcaster.broadcast and emitEvent calls with routeSystemSignal for backend connection.
    • Replaced direct broadcaster.broadcast and emitEvent calls with routeSystemSignal for backend disconnection.
    • Replaced direct broadcaster.broadcast and emitEvent calls with routeSystemSignal for draining pending passthroughs on backend error.
    • Replaced direct broadcaster.broadcast and emitEvent calls with routeSystemSignal for draining pending passthroughs on unexpected stream end.
  • src/core/consumer/consumer-gateway.test.ts
    • Updated createMockRuntime to include a process mock function.
    • Replaced emitted assertion for backend:relaunch_needed with mockRuntime.process assertion for BACKEND_RELAUNCH_NEEDED system signal.
    • Updated createHarness call to destructure mockRuntime instead of emitted.
    • Replaced emitted assertion with mockRuntime.process assertion for BACKEND_RELAUNCH_NEEDED system signal.
  • src/core/consumer/consumer-gateway.ts
    • Replaced direct emit call for backend:relaunch_needed with rt.process call for BACKEND_RELAUNCH_NEEDED system signal.
  • src/core/session-coordinator.ts
    • Modified emitEvent handling to only process session:closed events as system signals.
    • Added routeSystemSignal to the BackendConnector dependencies, routing signals through the session runtime.
    • Replaced direct runtime.transitionLifecycle call with runtime.process for SESSION_CLOSING system signal.
  • src/core/session/session-event.ts
    • Added new SystemSignal kinds: BACKEND_RELAUNCH_NEEDED, SESSION_CLOSING, SLASH_PASSTHROUGH_RESULT, and SLASH_PASSTHROUGH_ERROR.
  • src/core/session/session-reducer.ts
    • Implemented reduceSystemSignal logic for BACKEND_RELAUNCH_NEEDED to emit backend:relaunch_needed event.
    • Implemented reduceSystemSignal logic for SLASH_PASSTHROUGH_RESULT to broadcast slash_command_result and emit slash_command:executed.
    • Implemented reduceSystemSignal logic for SLASH_PASSTHROUGH_ERROR to broadcast slash_command_error and emit slash_command:failed.
    • Implemented reduceSystemSignal logic for BACKEND_CONNECTED to broadcast cli_connected and emit backend:connected, handling lifecycle transition.
    • Implemented reduceSystemSignal logic for BACKEND_DISCONNECTED to broadcast cli_disconnected and emit backend:disconnected, handling lifecycle transition.
    • Updated lifecycleForSignal to explicitly return null for BACKEND_CONNECTED and BACKEND_DISCONNECTED (as they are handled in reduceSystemSignal), and added SESSION_CLOSING to transition to 'closing'.
  • src/core/session/session-runtime.test.ts
    • Replaced direct runtime.transitionLifecycle calls with runtime.process calls for SESSION_CLOSING and SESSION_CLOSED system signals.
    • Updated test for invalid lifecycle transitions to use runtime.process with system signals and removed logger.warn assertion.
  • src/core/session/session-runtime.ts
    • Changed transitionLifecycle method visibility from public to private.
    • Removed applyLifecycleFromBackendMessage method.
  • src/testing/adapter-test-helpers.ts
    • Removed unused import for SystemSignal.
    • Modified emitEvent handling to only process session:closed events as system signals.
    • Added routeSystemSignal to the BackendConnector dependencies, routing signals through the session runtime.
    • Replaced direct runtime.transitionLifecycle call with runtime.process for SESSION_CLOSING system signal.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the application to route all state mutations through SessionRuntime.process() using system signals, addressing several architectural principle violations. The changes include removing dual lifecycle mutations, making transitionLifecycle() private, routing ConsumerGateway relaunch signals, and routing BackendConnector broadcasts and events through system signals. The changes involve modifications to several test files and core files, introducing a routeSystemSignal function and ensuring all state transitions are handled via the central process() method.

Comment thread src/core/session/session-runtime.ts
Comment thread src/core/session/session-reducer.ts Outdated
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@teng-lin teng-lin merged commit 1965e7e into main Feb 24, 2026
6 checks passed
@teng-lin teng-lin deleted the investigate-e2e branch February 25, 2026 03:35
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.

1 participant