# Implementation Plan: Conductor Path Configuration (conductor_path_configurable_20260306)

> **Reference:** [Spec](./spec.md) | [Architecture Guide](../../../docs/guide_architecture.md)
> 
> **CRITICAL:** This is Phase 0 infrastructure. Complete this before other Phase 3 tracks.

## Phase 1: Create Centralized Path Module
Focus: Establish the single source of truth for all paths

- [ ] Task 1.1: Initialize MMA Environment
    - Run `activate_skill mma-orchestrator` before starting

- [ ] Task 1.2: Create src/paths.py module
    - WHERE: `src/paths.py` (new file)
    - WHAT: Centralized path resolution module
    - HOW:
      ```python
      from pathlib import Path
      import os
      import tomllib
      from typing import Optional
      
      _CONFIG_PATH: Path = Path(os.environ.get("SLOP_CONFIG", "config.toml"))
      _RESOLVED: dict[str, Path] = {}
      
      def _resolve_path(env_var: str, config_key: str, default: str) -> Path:
       if env_var in os.environ:
        return Path(os.environ[env_var])
       try:
        with open(_CONFIG_PATH, "rb") as f:
         cfg = tomllib.load(f)
        if "paths" in cfg and config_key in cfg["paths"]:
         return Path(cfg["paths"][config_key])
       except FileNotFoundError:
        pass
       return Path(default)
      
      def get_conductor_dir() -> Path:
       if "conductor_dir" not in _RESOLVED:
        _RESOLVED["conductor_dir"] = _resolve_path("SLOP_CONDUCTOR_DIR", "conductor_dir", "conductor")
       return _RESOLVED["conductor_dir"]
      
      def get_logs_dir() -> Path:
       if "logs_dir" not in _RESOLVED:
        _RESOLVED["logs_dir"] = _resolve_path("SLOP_LOGS_DIR", "logs_dir", "logs/sessions")
       return _RESOLVED["logs_dir"]
      
      def get_scripts_dir() -> Path:
       if "scripts_dir" not in _RESOLVED:
        _RESOLVED["scripts_dir"] = _resolve_path("SLOP_SCRIPTS_DIR", "scripts_dir", "scripts/generated")
       return _RESOLVED["scripts_dir"]
      
      def get_config_path() -> Path:
       return _CONFIG_PATH
      
      def get_tracks_dir() -> Path:
       return get_conductor_dir() / "tracks"
      
      def get_track_state_dir(track_id: str) -> Path:
       return get_tracks_dir() / track_id
      
      def get_archive_dir() -> Path:
       return get_conductor_dir() / "archive"
      
      def reset_resolved() -> None:
       """For testing only - clear cached resolutions."""
       _RESOLVED.clear()
      ```
    - CODE STYLE: 1-space indentation
    - SAFETY: Lazy resolution prevents import-order issues

- [ ] Task 1.3: Write unit tests for paths module
    - WHERE: `tests/test_paths.py` (new file)
    - WHAT: Test path resolution logic
    - HOW: Test defaults, env vars, config overrides, precedence
    - PATTERN: Mock `os.environ`, create temp config files

## Phase 2: Update Core Modules
Focus: Migrate orchestrator and project_manager to use paths module

- [ ] Task 2.1: Update orchestrator_pm.py
    - WHERE: `src/orchestrator_pm.py` line 10
    - WHAT: Replace `CONDUCTOR_PATH` with path function
    - HOW:
      ```python
      # OLD: CONDUCTOR_PATH: Path = Path("conductor")
      # NEW:
      from src import paths
      # Then use paths.get_conductor_dir() where needed
      ```
    - SAFETY: Check all usages of `CONDUCTOR_PATH` in the file

- [ ] Task 2.2: Update project_manager.py
    - WHERE: `src/project_manager.py` lines 240, 252, 297
    - WHAT: Replace hardcoded "conductor" with path functions
    - HOW:
      ```python
      from src import paths
      # save_track_state: track_dir = paths.get_track_state_dir(track_id)
      # load_track_state: state_file = paths.get_track_state_dir(track_id) / "state.toml"
      # get_all_tracks: tracks_dir = paths.get_tracks_dir()
      ```
    - SAFETY: Maintain `base_dir` parameter for backward compatibility if needed

## Phase 3: Update Session Logger
Focus: Migrate session_logger.py to use paths module

- [ ] Task 3.1: Update session_logger.py paths
    - WHERE: `src/session_logger.py` lines 26-27
    - WHAT: Replace module-level constants with lazy resolution
    - HOW:
      ```python
      # OLD:
      # _LOG_DIR: Path = Path("./logs/sessions")
      # _SCRIPTS_DIR: Path = Path("./scripts/generated")
      # NEW:
      from src import paths
      # In functions, use paths.get_logs_dir() and paths.get_scripts_dir()
      ```
    - SAFETY: Module-level initialization may need to become function-level

- [ ] Task 3.2: Handle open_session() path resolution
    - WHERE: `src/session_logger.py` open_session function
    - WHAT: Resolve paths at call time, not import time
    - HOW: Call `paths.get_logs_dir()` inside `open_session()`
    - SAFETY: Verify no import-time side effects

## Phase 4: Update App Controller
Focus: Migrate all scattered path references in app_controller.py

- [ ] Task 4.1: Update app_controller.py log paths
    - WHERE: `src/app_controller.py` lines 643, 674, 1241
    - WHAT: Replace hardcoded "logs/sessions" with path functions
    - HOW:
      ```python
      from src import paths
      # cb_load_prior_log: initialdir=str(paths.get_logs_dir())
      # cb_prune_logs: LogRegistry(paths.get_logs_dir() / "log_registry.toml")
      # _render_log_management: Path(paths.get_logs_dir())
      ```
    - SAFETY: Convert Path to str where file dialog expects string

- [ ] Task 4.2: Update app_controller.py conductor paths
    - WHERE: `src/app_controller.py` lines 1907, 1937
    - WHAT: Replace hardcoded "conductor" with path functions
    - HOW:
      ```python
      from src import paths
      # _render_projects_panel: base = paths.get_conductor_dir()
      # _render_projects_panel: track_dir = paths.get_tracks_dir() / track_id
      ```
    - SAFETY: None

## Phase 5: Update GUI
Focus: Migrate gui_2.py path references

- [ ] Task 5.1: Update gui_2.py log path
    - WHERE: `src/gui_2.py` line 776
    - WHAT: Replace hardcoded LogRegistry path
    - HOW:
      ```python
      from src import paths
      # LogRegistry(paths.get_logs_dir() / "log_registry.toml")
      ```
    - SAFETY: None

## Phase 6: Configuration Support
Focus: Add paths section to config.toml

- [ ] Task 6.1: Add [paths] section to config.toml
    - WHERE: `config.toml`
    - WHAT: Add documented paths section
    - HOW:
      ```toml
      # Path Configuration (optional - defaults shown)
      # Override with environment variables: SLOP_CONDUCTOR_DIR, SLOP_LOGS_DIR, SLOP_SCRIPTS_DIR
      
      [paths]
      # conductor_dir = "conductor"
      # logs_dir = "logs/sessions"
      # scripts_dir = "scripts/generated"
      ```
    - SAFETY: Comments-only defaults don't change behavior

- [ ] Task 6.2: Document environment variables
    - WHERE: `conductor/tech-stack.md` or `README.md`
    - WHAT: Add documentation for path environment variables
    - HOW: Table of env vars with descriptions

## Phase 7: Verification
Focus: Ensure all changes work correctly

- [ ] Task 7.1: Run full test suite
    - COMMAND: `uv run pytest tests/ -v --timeout=60`
    - EXPECTED: All existing tests pass
    - BATCHING: Run in batches of 4 files max

- [ ] Task 7.2: Test with custom paths
    - HOW: Set env vars, verify app uses custom paths
    - VERIFY: Check logs go to custom dir, tracks load from custom dir

- [ ] Task 7.3: Test default behavior unchanged
    - HOW: Run without env vars, verify defaults work
    - VERIFY: All paths resolve to original defaults

- [ ] Task 7.4: Conductor - Phase Verification
    - Run: `uv run pytest tests/test_paths.py -v`
    - Manual: Start app, verify no path-related errors

## Implementation Notes

### Import Order Considerations
- `paths.py` must not import from other src modules
- Other modules can safely import from `paths.py`
- `session_logger.py` needs careful handling due to module-level state

### Backward Compatibility
- All existing `base_dir` parameters continue to work
- Default behavior is unchanged when no config/env overrides
- Existing `SLOP_CONFIG` env var pattern is preserved

### Files Modified
- `src/paths.py` (new)
- `src/orchestrator_pm.py`
- `src/project_manager.py`
- `src/session_logger.py`
- `src/app_controller.py`
- `src/gui_2.py`
- `config.toml`
- `tests/test_paths.py` (new)

### Code Style Checklist
- [ ] 1-space indentation throughout
- [ ] CRLF line endings on Windows
- [ ] No comments unless documenting public API
- [ ] Type hints on all public functions
- [ ] Follow existing module patterns
