Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/channels/web/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Browser-facing HTTP API and SSE/WebSocket real-time streaming. Axum-based, singl
| `platform/state.rs` | `GatewayState`, `RateLimiter`, `PerUserRateLimiter`, `WorkspacePool`, `FrontendHtmlCache`, `FrontendCacheKey`, `ActiveConfigSnapshot`, `PromptQueue`, `RoutineEngineSlot`. Canonical home for shared gateway state. |
| `platform/static_files.rs` | CSP directive set + `BASE_CSP_HEADER` (single source of truth), frontend HTML bundle assembly (`build_frontend_html`), and the unauthenticated static handlers: `/`, `/style.css`, `/app.js`, `/theme.css`, `/favicon.ico`, `/i18n/*`, `/admin*`, `/api/health`, plus the authenticated `/projects/{id}/...` file-serving routes. |
| `types.rs` | Request/response DTOs and `SseEvent` enum (source of truth for SSE contract) |
| `sse.rs` | `SseManager` — broadcast channel that fans out `SseEvent` to all connected SSE clients |
| `ws.rs` | WebSocket handler (`handle_ws_connection`) + `WsConnectionTracker` |
| `auth.rs` | Bearer token middleware (`Authorization: Bearer <GATEWAY_AUTH_TOKEN>`) |
| `platform/sse.rs` | `SseManager` — broadcast channel that fans out `SseEvent` to all connected SSE clients. Re-exported as `channels::web::sse` for backward compat. |

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

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

This entry says SseManager fans out SseEvent, but platform/sse.rs actually broadcasts AppEvent. Please update the type name in this description so the docs match the current SSE contract type.

Suggested change
| `platform/sse.rs` | `SseManager` — broadcast channel that fans out `SseEvent` to all connected SSE clients. Re-exported as `channels::web::sse` for backward compat. |
| `platform/sse.rs` | `SseManager` — broadcast channel that fans out `AppEvent` to all connected SSE clients. Re-exported as `channels::web::sse` for backward compat. |

Copilot uses AI. Check for mistakes.
| `platform/ws.rs` | WebSocket handler (`handle_ws_connection`) + `WsConnectionTracker`. Re-exported as `channels::web::ws`. |
| `platform/auth.rs` | Bearer token middleware (`Authorization: Bearer <GATEWAY_AUTH_TOKEN>`) + DB-token + OIDC extractors. Re-exported as `channels::web::auth`. |
| `log_layer.rs` | Tracing layer that tees log lines to the `/api/logs/events` SSE stream |
| `handlers/` | Feature handler functions split by domain: `auth`, `chat`, `engine`, `extensions`, `frontend`, `jobs`, `llm`, `memory`, `routines`, `secrets`, `settings`, `skills`, `system_prompt`, `tokens`, `tool_policy`, `users`, `webhooks`. Targeted for migration into `features/<slice>/` per ironclaw#2599. |
| `openai_compat.rs` | OpenAI-compatible proxy (`/v1/chat/completions`, `/v1/models`) |
Expand Down
14 changes: 10 additions & 4 deletions src/channels/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,25 @@
//! ◄── GET / ───────────────── Static HTML/CSS/JS
//! ```

pub mod auth;
pub(crate) mod handlers;
pub mod log_layer;
pub mod oauth;
pub(crate) mod onboarding;
pub mod openai_compat;
pub(crate) mod platform;
pub mod platform;
pub mod responses_api;
pub mod server;
pub mod sse;
pub mod types;
pub(crate) mod util;
pub mod ws;

// Backward-compat re-exports for the ironclaw#2599 migration. The auth,
// SSE, and WebSocket modules moved to `platform::*` in stage 3; every
// existing `crate::channels::web::{auth,sse,ws}::...` call site
// continues to resolve via these re-exports until a follow-up PR
// updates them directly.
pub use platform::auth;
pub use platform::sse;
pub use platform::ws;

/// Test helpers for gateway integration tests.
///
Expand Down
File renamed without changes.
24 changes: 13 additions & 11 deletions src/channels/web/platform/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
//! Platform layer for the web gateway.
//!
//! This submodule holds the gateway's transport and framing concerns: shared
//! state, the Axum route composition, static asset serving, and (in later
//! stages of ironclaw#2599) auth / SSE / WS.
//! This submodule holds the gateway's transport and framing concerns:
//! shared state, the Axum route composition, static asset serving, bearer
//! / OIDC auth, and the SSE / WebSocket broadcast fan-out.
//!
//! **Dependency direction.** Feature handlers (under `handlers/` today,
//! `features/<slice>/` later) depend on platform types (`GatewayState`,
//! rate limiters, auth extractors). Platform *submodules* do **not**
//! reach back into feature handlers — with the single, intentional
//! exception of [`router`], which is the composition point. The router
//! imports every feature handler it registers; that is its job. The
//! "no back-edges" rule enforced by future CI (ironclaw#2599 stage 5)
//! applies to `platform/state.rs`, `platform/static_files.rs`, and the
//! auth/SSE/WS modules once they move here — not to `router`, whose
//! whole purpose is to wire features onto the transport.
//! rate limiters, auth extractors, `SseManager`, `WsConnectionTracker`).
//! Platform *submodules* do **not** reach back into feature handlers —
//! with the single, intentional exception of [`router`], which is the
//! composition point. The router imports every feature handler it
//! registers; that is its job. The "no back-edges" rule enforced by
//! future CI (ironclaw#2599 stage 5) applies to every platform module
//! except `router`.
Comment on lines +10 to +15

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.

medium

The documentation states that platform submodules do not reach back into feature handlers, and that this rule applies to every platform module except router. However, the newly relocated auth and ws modules still contain dependencies on feature handlers and server.rs (e.g., check_email_domain in auth.rs and handle_legacy_auth_token_submission in ws.rs).

While this is a staged migration and the rule is "enforced by future CI", declaring that it "applies" to these modules now creates an inconsistency between the documentation and the implementation. Consider updating the comment to clarify that this is the target architecture.

Suggested change
//! Platform *submodules* do **not** reach back into feature handlers —
//! with the single, intentional exception of [`router`], which is the
//! composition point. The router imports every feature handler it
//! registers; that is its job. The "no back-edges" rule enforced by
//! future CI (ironclaw#2599 stage 5) applies to every platform module
//! except `router`.
//! Platform *submodules* are intended to **not** reach back into feature
//! handlers — with the single, intentional exception of router, which
//! is the composition point. The router imports every feature handler it
//! registers; that is its job. The "no back-edges" rule (to be enforced
//! by CI in ironclaw#2599 stage 5) is the target state for every platform
//! module except router.

Comment on lines +10 to +15

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

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

The module-level docs here state that every platform module except router must not reach back into feature handlers. In this PR, platform/auth.rs depends on handlers::auth and platform/ws.rs depends on server::*, so the documented rule isn’t currently true. Either address those back-edges as part of the move, or update this doc comment to call out the temporary exceptions during the migration.

Suggested change
//! Platform *submodules* do **not** reach back into feature handlers —
//! with the single, intentional exception of [`router`], which is the
//! composition point. The router imports every feature handler it
//! registers; that is its job. The "no back-edges" rule enforced by
//! future CI (ironclaw#2599 stage 5) applies to every platform module
//! except `router`.
//! Platform *submodules* should not reach back into feature handlers.
//! Today, during the staged migration, there are temporary exceptions:
//! [`router`] remains the intentional composition point, and `auth` and
//! `ws` still have back-edges that have not yet been removed. The router
//! imports every feature handler it registers; that is its job. The
//! "no back-edges" rule enforced by future CI (ironclaw#2599 stage 5) is
//! the target architecture for all platform modules once those temporary
//! exceptions are eliminated.

Copilot uses AI. Check for mistakes.
//!
//! See `src/channels/web/CLAUDE.md` for the staged migration plan.

pub mod auth;
pub mod router;
pub mod sse;
pub mod state;
pub mod static_files;
pub mod ws;
File renamed without changes.
File renamed without changes.
Loading