Skip to content

app-logic: group SessionParts fields into AiConfig, SafetyState, ChatPersistence and TransportState #871

Open

Description

@smart-ssh-planner

Goal

A session's state is grouped by concern instead of 44 flat public fields, so code that needs only the AI configuration or only the safety flags takes that part, and it is obvious which fields belong to the safety model.

Context

crates/app-logic/src/session.rs (2,678 lines) defines pub struct SessionParts (:696) with 44 pub fields; Session derefs to it (:685–690). Fields (on develop): transport, ai_provider, ai_provider_budget, context, filter_engine, server_id, tags, terminal, redactor, ai_provider_label, ai_model, system_context_parts, model_context_window_tokens, summary, context_usage, mcp_origin_flags, sudo_password, status, pending_action, mcp_confirmation_claim, auto_continue_stop, auto_continue_stop_notify, chat_turn, risk_second_opinion_provider, risk_second_opinion_budget, red_risk_always_confirm, running_command_cancellations, outgoing_transform, chat_content, untrusted_content_ingested, post_ingest_policy, injection_check_provider, injection_check_budget, injection_suspected, injection_suspected_reason, injection_check_unavailable, second_opinion_setup_notice_pending, injection_check_inactive_notice_pending, chat_session_store, ledger_store, chat_session_id, ai_request_paced_at, auto_reconnect. About 20 set_*_for_tests setters (:1292–1431) sit on the production type behind cfg(any(test, feature = "test-support")). SessionParts is built in the session builder in app-logic::connect (previous refactoring) and in test support (crates/app-logic/src/test_support.rs, orchestration/test_support.rs).

Crates outside this workspace that embed app-logic access session.transport, session.server_id and session.redactor.

Requirements

  • Introduce sub-structures, each in its own file under crates/app-logic/src/session/ (convert session.rs to session/mod.rs):
    • AiConfig: AI provider, budget, label, model, context, system context parts, context window, summary, context usage, request pacing;
    • SafetyState: filter engine, sudo password, risk second opinion provider/budget, red-risk-always-confirm, outgoing transform, untrusted-content flag, post-ingest policy, injection check provider/budget/flags/reason, notice-pending flags, MCP origin flags and confirmation claim;
    • ChatPersistence: chat session store, ledger store, chat session id, chat content registry;
    • TransportState: terminal, status, auto reconnect, running command cancellations, pending action, chat turn and auto-continue stop (adjust the grouping where a field clearly belongs elsewhere and explain it in the PR).
  • transport, server_id, tags and redactor stay direct fields of SessionParts (public API used by embedding crates).
  • Move the set_*_for_tests setters into session/test_setters.rs inside one #[cfg(any(test, feature = "test-support"))] impl Session block (if not already done by an earlier test-extraction issue), adapted to the new paths.
  • Update all users in app-logic and app-shell.

Acceptance Criteria

  • SessionParts has at most 10 direct fields; transport, server_id, tags and redactor are among them and keep their types.
  • Every file under crates/app-logic/src/session/ is below 1,200 lines (production).
  • cargo build --workspace passes without the test-support feature (no production call into a test setter).
  • The module-cycle ceiling test (from the dto split) still passes without raising the ceiling.
  • Test count per binary unchanged; all pass.
  • Gate green.

Technical Notes

  • Many of these fields are part of the safety model (filter engine, sudo password, redactor, injection and second-opinion flags). Moving them must not change when they are read or written, nor lock scopes (StdMutex/AsyncMutex stay per field, no new lock around a whole sub-structure). Read .claude/skills/smart-ssh-coder/references/security-invariants.md.
  • Restructuring only: behaviour, error codes, emitted events, log fields and messages stay identical. Fix nothing on the way; a bug you find goes into its own issue (mention it in the PR).
  • Tests: cargo test --workspace -- --list before and after; the number of tests per test binary does not decrease, and the same tests pass. Tests may move with the code they test (<module>/tests.rs or <module>/tests_<topic>.rs; no new *_tests.rs names).
  • Public items used from outside the crate keep their paths (re-export if an item moves); check with grep -rn over the workspace.
  • New code comments in English; existing German comments may move unchanged.
  • Update docs/architecture.md (module table "Ausnahmen von der Regel (A4)" and the list of app-shell modules) when a module moves between app-shell and app-logic.
  • Gate: cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace, cargo build --workspace (the last one catches production calls into test-support-only items).

Spec impact: none

Related Work

Activity

  1. added this to the 0.8.0 milestone on Oct 26, 2026
  2. 23 remaining items

  3. marked this as blocking 15 issues on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Fields

    Priority

    P2 - Normal

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions