refactor: split session.rs into directory module (FM-1, FM-2, FM-3) #63

Merged
jesse merged 6 commits from chore/split-session-tools into main 2026-05-04 06:33:45 +02:00
Owner

Summary

  • FM-1: split crates/cognix-mcp/src/tools/session.rs (752 lines) into session/{mod,create,get,list}.rs. Public API preserved via thin facade mod.rs (pub use).
  • FM-2: add S-20 path-traversal criterion in notes/cognix-evaluation-guide.md section 3.3 + test_write_tool_rejects_parent_traversal_outside_workspace integration test.
  • FM-3: cross-reference tests/integration/q02_tool_matrix.rs from section 5 of evaluation guide.
  • Hardening (10a722f): tighten filesystem path normalization (Windows Prefix participates in workspace check, parent-traversal rejection in relative components) and surface previously-swallowed session storage failures via the response warnings field.

Fail-open visibility changes (10a722f)

The hardening commit makes three observable changes to session-tool responses. Each strengthens fail-open observability per .claude/rules/patterns.md (DegradedResult<T>); none change happy-path output.

Handler Before After
handle_create_session storage failure silently swallowed; only the new ID returned appends session persistence degraded: … to the response warnings array; ID still returned
handle_get_session storage error masked as "session not found" distinguishes storage error from genuine "not found" in the response text
handle_list_sessions storage failure returned a clean empty list adds a warnings field describing the degraded read; list field still present

All three behaviors are covered by tests in session/{create,get,list}.rs.

FM-DG-01 layout decision

Directory module: session/{mod,create,get,list}.rs. internal.rs not created — no shared implementation items qualified; mod.rs is 9 physical lines (well under the 100-line threshold). make_storage (3-line test fixture) duplicated into each test module rather than shared.

File sizes (post-split)

File Lines
mod.rs 9
get.rs 170
create.rs 263
list.rs 307

All under the 400-line target; none exceed the 800-line hard limit.

Test attribution

9 tests to create.rs, 4 to get.rs, 5 to list.rs. None spanned multiple handlers.

Public API gate (fallback)

All 6 pre-split public symbols re-exported from session/mod.rs via pub use: create_session_definition, handle_create_session, get_session_definition, handle_get_session, list_sessions_definition, handle_list_sessions. cognix-server builds unchanged.

Platform coverage note

The new Prefix arm in normalize_absolute_components is exercised by test_normalize_absolute_components_preserves_windows_prefix and test_normalize_workspace_relative_path_allows_valid_windows_workspace_path, both #[cfg(windows)]. Linux CI cannot reach the branch because Path::components() never yields Prefix outside Windows; the arm is documented inline at crates/cognix-server/src/registration/filesystem.rs.

Test plan

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace (2743 passed, 9 ignored)
  • cargo build --release --workspace
  • cargo doc with strict RUSTDOCFLAGS
  • File-size check returns nothing
  • New integration test test_write_tool_rejects_parent_traversal_outside_workspace passes

Self-Review Checklist

  • No hardcoded secrets
  • No unwrap() in library code
  • No println!/dbg!/eprintln!
  • Fail-open behavior preserved
  • Tests cover happy path and error cases
## Summary - FM-1: split `crates/cognix-mcp/src/tools/session.rs` (752 lines) into `session/{mod,create,get,list}.rs`. Public API preserved via thin facade `mod.rs` (`pub use`). - FM-2: add S-20 path-traversal criterion in `notes/cognix-evaluation-guide.md` section 3.3 + `test_write_tool_rejects_parent_traversal_outside_workspace` integration test. - FM-3: cross-reference `tests/integration/q02_tool_matrix.rs` from section 5 of evaluation guide. - Hardening (10a722f): tighten filesystem path normalization (Windows `Prefix` participates in workspace check, parent-traversal rejection in relative components) and surface previously-swallowed session storage failures via the response `warnings` field. ## Fail-open visibility changes (10a722f) The hardening commit makes three observable changes to session-tool responses. Each strengthens fail-open observability per `.claude/rules/patterns.md` (`DegradedResult<T>`); none change happy-path output. | Handler | Before | After | |---|---|---| | `handle_create_session` | storage failure silently swallowed; only the new ID returned | appends `session persistence degraded: …` to the response `warnings` array; ID still returned | | `handle_get_session` | storage error masked as "session not found" | distinguishes storage error from genuine "not found" in the response text | | `handle_list_sessions` | storage failure returned a clean empty list | adds a `warnings` field describing the degraded read; list field still present | All three behaviors are covered by tests in `session/{create,get,list}.rs`. ## FM-DG-01 layout decision Directory module: `session/{mod,create,get,list}.rs`. `internal.rs` **not created** — no shared implementation items qualified; `mod.rs` is 9 physical lines (well under the 100-line threshold). `make_storage` (3-line test fixture) duplicated into each test module rather than shared. ## File sizes (post-split) | File | Lines | |---|---| | `mod.rs` | 9 | | `get.rs` | 170 | | `create.rs` | 263 | | `list.rs` | 307 | All under the 400-line target; none exceed the 800-line hard limit. ## Test attribution 9 tests to `create.rs`, 4 to `get.rs`, 5 to `list.rs`. None spanned multiple handlers. ## Public API gate (fallback) All 6 pre-split public symbols re-exported from `session/mod.rs` via `pub use`: `create_session_definition`, `handle_create_session`, `get_session_definition`, `handle_get_session`, `list_sessions_definition`, `handle_list_sessions`. `cognix-server` builds unchanged. ## Platform coverage note The new `Prefix` arm in `normalize_absolute_components` is exercised by `test_normalize_absolute_components_preserves_windows_prefix` and `test_normalize_workspace_relative_path_allows_valid_windows_workspace_path`, both `#[cfg(windows)]`. Linux CI cannot reach the branch because `Path::components()` never yields `Prefix` outside Windows; the arm is documented inline at `crates/cognix-server/src/registration/filesystem.rs`. ## Test plan - [x] `cargo fmt --check` - [x] `cargo clippy --workspace --all-targets -- -D warnings` - [x] `cargo test --workspace` (2743 passed, 9 ignored) - [x] `cargo build --release --workspace` - [x] `cargo doc` with strict RUSTDOCFLAGS - [x] File-size check returns nothing - [x] New integration test `test_write_tool_rejects_parent_traversal_outside_workspace` passes ## Self-Review Checklist - [x] No hardcoded secrets - [x] No `unwrap()` in library code - [x] No `println!`/`dbg!`/`eprintln!` - [x] Fail-open behavior preserved - [x] Tests cover happy path and error cases
refactor: split session.rs into directory module
Some checks failed
CI / Detect Changes (pull_request) Successful in 11s
CI / Security Scan (pull_request) Successful in 17s
CI / Format (pull_request) Successful in 18s
CI / D-02 Clean Build Gate (pull_request) Failing after 1s
CI / Integration Tests (pull_request) Has been skipped
CI / Benchmarks (pull_request) Has been skipped
CI / Conventional Validation (pull_request) Successful in 39s
CI / Check file lengths (pull_request) Successful in 31s
CI / Documentation (pull_request) Successful in 2m41s
CI / Clippy (pull_request) Successful in 3m25s
CI / Check (linux-aarch64 compile-validation) (pull_request) Successful in 3m18s
CI / Deny (pull_request) Successful in 6m39s
CI / Clean Build Sample 1 (pull_request) Successful in 9m16s
CI / Clean Build Sample 3 (pull_request) Successful in 9m18s
CI / Audit (CVEs) (pull_request) Successful in 9m45s
CI / Clean Build Sample 2 (pull_request) Successful in 9m21s
CI / Clean Build Summary (pull_request) Has been skipped
CI / Test (pull_request) Successful in 9m55s
CI / RSS gate (P-15) (pull_request) Successful in 7m40s
CI / Coverage (80% gate) (pull_request) Successful in 11m14s
CI / Build (release) (pull_request) Successful in 8m16s
CI / PR Size Check (pull_request) Successful in 9s
CI / CI Report (pull_request) Successful in 3s
76f0619d47
FM-1: Split crates/cognix-mcp/src/tools/session.rs (752 lines) into
session/{mod,create,get,list}.rs to stay below 800-line ceiling and
unblock the planned file-length CI gate.

Public API preserved via thin facade `mod.rs` (pub use).

FM-2: add S-20 path-traversal criterion + parent-traversal test.
FM-3: cross-reference q02_tool_matrix.rs from §5 of evaluation guide.

File sizes:
  create.rs 263 lines
  get.rs    170 lines
  list.rs   307 lines
  mod.rs      9 lines (thin facade)
chore: address PR #63 review nits (L2, L3)
Some checks failed
CI / Detect Changes (pull_request) Successful in 11s
CI / Integration Tests (pull_request) Has been skipped
CI / Benchmarks (pull_request) Has been skipped
CI / Format (pull_request) Successful in 18s
CI / Security Scan (pull_request) Successful in 18s
CI / Conventional Validation (pull_request) Successful in 39s
CI / Clean Build Sample 3 (pull_request) Failing after 3s
CI / Check file lengths (pull_request) Successful in 38s
CI / Documentation (pull_request) Successful in 2m44s
CI / Check (linux-aarch64 compile-validation) (pull_request) Successful in 3m14s
CI / Clippy (pull_request) Successful in 3m31s
CI / Deny (pull_request) Successful in 6m29s
CI / D-02 Clean Build Gate (pull_request) Successful in 8m16s
CI / Clean Build Sample 1 (pull_request) Successful in 8m23s
CI / Clean Build Sample 2 (pull_request) Successful in 8m24s
CI / Audit (CVEs) (pull_request) Successful in 8m53s
CI / Clean Build Summary (pull_request) Has been skipped
CI / Test (pull_request) Successful in 9m18s
CI / Coverage (80% gate) (pull_request) Successful in 10m34s
CI / RSS gate (P-15) (pull_request) Successful in 7m16s
CI / Build (release) (pull_request) Successful in 7m40s
CI / PR Size Check (pull_request) Successful in 7s
CI / CI Report (pull_request) Successful in 4s
3b61f71cbf
L2: document Windows-only Prefix arm in normalize_absolute_components
    (Path::components never yields Prefix on Unix, so coverage lives in
    the cfg(windows) tests).
L3: drop unused clippy::panic allow from file_tools_mcp.rs to match the
    existing integration-test convention (unwrap_used only).
ci: keep clean build samples on main
All checks were successful
CI / Detect Changes (pull_request) Successful in 9s
CI / Benchmarks (pull_request) Has been skipped
CI / Integration Tests (pull_request) Has been skipped
CI / Security Scan (pull_request) Successful in 17s
CI / Format (pull_request) Successful in 18s
CI / Conventional Validation (pull_request) Successful in 38s
CI / Clean Build Sample 1 (pull_request) Has been skipped
CI / Clean Build Sample 2 (pull_request) Has been skipped
CI / Clean Build Sample 3 (pull_request) Has been skipped
CI / Clean Build Summary (pull_request) Has been skipped
CI / Check file lengths (pull_request) Successful in 29s
CI / Documentation (pull_request) Successful in 2m3s
CI / Check (linux-aarch64 compile-validation) (pull_request) Successful in 2m25s
CI / Clippy (pull_request) Successful in 2m27s
CI / D-02 Clean Build Gate (pull_request) Successful in 3m38s
CI / Deny (pull_request) Successful in 5m23s
CI / Audit (CVEs) (pull_request) Successful in 5m33s
CI / Test (pull_request) Successful in 6m23s
CI / Coverage (80% gate) (pull_request) Successful in 7m10s
CI / RSS gate (P-15) (pull_request) Successful in 5m13s
CI / Build (release) (pull_request) Successful in 5m36s
CI / PR Size Check (pull_request) Successful in 9s
CI / CI Report (pull_request) Successful in 4s
052a3117f7
jesse merged commit a99b828ca6 into main 2026-05-04 06:33:45 +02:00
jesse deleted branch chore/split-session-tools 2026-05-04 06:33:45 +02:00
Sign in to join this conversation.
No reviewers
No labels
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
jesse/cognix!63
No description provided.