# review-001-007 ## result - approved ## findings ### Build dependency tasks (001-003) - `infrastructure/build.gradle`: `implementation project(":core:router")` added correctly. Dependency ordering is clean — router is added before inference and approvals in the dependency block. - `apps/server/build.gradle`: `implementation project(':core:router')` added correctly. Placed between inference and tools dependencies, which is a reasonable ordering. - `core/router/build.gradle`: All four spec-required dependencies declared (`:core:events`, `:core:context`, `:core:inference`, `:core:sessions`). The task notes correctly observe that `:core:inference` transitively depends on `:core:events` and `:core:context`, but `implementation` deps do not propagate, so explicit declarations are necessary. No cross-core dependency violations detected — `:core:router` does not depend on any sibling core modules. ### Event definition task (004) - `SteeringNoteAddedEvent` correctly defined in `ContextEvents.kt` with fields `sessionId: SessionId`, `content: String`, `stageId: StageId? = null` matching the task spec. - `@Serializable` annotation added — this is a sensible addition for round-trip serialization and follows the pattern of other events in the file. - Event is an `EventPayload` subclass, consistent with the existing pattern. ### Serialization registration task (005) - Import added in alphabetical order among event imports (`SteeringNoteAddedEvent` after `SessionStartedEvent`). - `subclass(SteeringNoteAddedEvent::class)` registered after `SessionFailedEvent` and before `StageStartedEvent` in the `eventModule` polymorphic block. - All 8 pre-existing `:core:events` tests pass. - Detekt passes on `:core:router` and `:core:context`; pre-existing `NewLineAtEndOfFile` warnings in `:core:events` are unrelated to this change (noted in task-005). ### RouterState model task (006) - `RouterState` correctly defined as `@Serializable` data class with all spec-required fields: `sessionId`, `workflowStatus`, `currentStageId`, `l2Memory`, `conversationHistory`. - Supporting enums correctly defined: `WorkflowStatus` (IDLE, RUNNING, PAUSED, COMPLETED, FAILED), `StageOutcomeKind` (SUCCESS, FAILURE, CANCELLED), `TurnRole` (USER, ROUTER). - All fields use sensible empty defaults (`IDLE`, `null`, `emptyList()`). - `RouterL2Entry` and `RouterTurn` defined with `Instant` timestamps (imported from `kotlinx.datetime`). - `WorkflowStatus`, `StageOutcomeKind`, and `TurnRole` are locally defined in the router module (not imported from `:core:events`), keeping router types self-contained per task notes. - No reducer logic implemented (per task non-goals). ### RouterConfig model task (007) - `RouterConfig` correctly defined as `@Serializable` data class with `keepLast: Int = 10` and `tokenBudget: TokenBudget = TokenBudget(limit = 5000)` matching spec defaults. - `TokenBudget` (pre-existing in `:core:context`) correctly annotated with `@Serializable` to enable its use as a field type in `RouterConfig`. The annotation is minimal and safe — `TokenBudget` only has `Int` properties. - No unused imports in any new file. ### Compilation & static analysis - All affected modules compile: `:infrastructure`, `:apps:server`, `:core:router`, `:core:events`, `:core:context` — BUILD SUCCESSFUL. - Detekt passes on `:core:router` and `:core:context`; no new warnings introduced. - All 8 `:core:events` tests pass. ## missing requirements The following spec requirements are explicitly deferred to later tasks (per task non-goals) and are **not** missing — they are intentionally out of scope for tasks 001-007: - `RouterReducer`, `RouterProjector`, `RouterRepository` (Tasks 009-011 in plan) - `RouterContextBuilder` (Task 012 in plan) - `RouterFacade` (Task 013 in plan) - `ChatMode`, `ChatInput`, `RouterResponseMessage` protocol types (Tasks 014-015 in plan) - WebSocket handler wiring (Task 016 in plan) - `InfrastructureModule` wiring for `RouterFacade` (Task 018 in plan) - Deterministic tests (Tasks 020-023 in plan) - `SteeringNote` domain data class (deferred per task-004 notes) No unplanned gaps detected in the implemented scope. ## edge cases - **TokenBudget serialization tests**: No pre-existing serialization test exists for `TokenBudget` in `:core:events` tests or `testing/` submodules. The `@Serializable` annotation was added but not verified with an explicit round-trip test. This is low risk given `TokenBudget` has only `Int` properties, but a serialization test would be advisable before `TokenBudget` is used in more complex serializable types. - **SteeringNoteAddedEvent serialization test**: The task notes correctly identify that no serialization round-trip test exists for `SteeringNoteAddedEvent`. The registration in `eventModule` prevents silent runtime deserialization failure (the primary safety concern), but an explicit round-trip test would provide higher confidence. - **`NewLineAtEndOfFile` detekt warnings**: 15 files in `:core:events` have this warning. None are new (confirmed pre-existing per task-005). The `Serialization.kt` file that was modified is among them. This is a known cosmetic issue that does not affect correctness. - **Dependency declaration completeness**: `:core:router` declares `:core:inference` and `:core:sessions` as dependencies, but the current source files (`RouterState.kt`, `RouterConfig.kt`) do not directly import from these modules. This is correct for the current phase (types are needed for subsequent tasks) but will produce unused-import warnings once source files are added and the unused deps are still present. ## suggested follow-up 1. **Add serialization round-trip test for `TokenBudget`** — low effort, high confidence gain. Add to `:core:context` or `testing/deterministic` once that test module is set up (depends on Task 019). 2. **Add serialization round-trip test for `SteeringNoteAddedEvent`** — should be paired with the first test that actually exercises the event in the event store pipeline. 3. **Proceed with Tasks 008-010** (RouterResponse, RouterReducer, RouterProjector) as the natural next phase — the foundational types from tasks 001-007 are correctly in place and ready to be consumed.