Goal
Move core-specific types from shared types/ layer into core/types/ to follow Clean Architecture principles where domain types live in the domain layer.
Non-goals:
- Changing the shared types that are correctly utils-level
- Adding re-export indirection layers
- Modifying any business logic
Scope & Assumptions
In scope:
- Create
src/tunacode/core/types/directory structure - Move 9 core-specific types to
core/types/ - Update 17 files in core to import from new location
- Delete 2 dead types (CommandContext, ProcessRequestCallback)
- Update DEPENDENCY_MAP.md
Out of scope:
- Changes to UI layer
- Changes to tools layer
- New features or behavior changes
Assumptions:
- The existing
core/types.pyre-export pattern can be expanded - Tests pass after import path changes
- No circular import issues will arise
Deliverables (DoD)
src/tunacode/core/types/directory with moved types- All 17 core files updated to import from
core/types/ - Dead code deleted from
types/dataclasses.pyandtypes/callbacks.py ruff checkpassesuv run pytestpasses- DEPENDENCY_MAP.md updated
Readiness (DoR)
- Research document complete
- Best practice verified (Clean Architecture standard)
- File inventory complete (17 files, 26 imports)
- Types categorized (9 to move, 2 to delete)
Milestones
- M1: Create core/types/ structure and move types
- M2: Update all import statements
- M3: Delete dead code and verify
Work Breakdown (Tasks)
Task 1: Create core/types/ directory structure
Summary: Create the directory and initial __init__.py
Files: src/tunacode/core/types/__init__.py
Acceptance:
- Directory exists
__init__.pyexports nothing yet (placeholder)
Task 2: Move core-specific types to core/types/
Summary: Move 9 types from types/ to core/types/
Types to move:
ResponseState(from dataclasses.py)AgentState(from dataclasses.py)StateManagerProtocol(from state.py)SessionStateProtocol(from state.py)ConversationState(from state_structures.py)TaskState(from state_structures.py)RuntimeState(from state_structures.py)UsageState(from state_structures.py)ToolCallRegistry(from tool_registry.py)
Files touched:
- Create:
src/tunacode/core/types/state.py - Create:
src/tunacode/core/types/protocols.py - Create:
src/tunacode/core/types/registry.py - Update:
src/tunacode/core/types/__init__.py
Acceptance:
- All 9 types defined in core/types/
- Exports work via
from tunacode.core.types import X
Task 3: Update 17 core files to import from core/types/
Summary: Change import statements from tunacode.types to tunacode.core.types for moved types
Files to update (17):
core/state.pycore/user_configuration.pycore/lsp_status.pycore/types.py(the re-export file)core/configuration.pycore/logging/manager.pycore/agents/main.pycore/agents/agent_components/agent_config.pycore/agents/agent_components/agent_helpers.pycore/agents/agent_components/response_state.pycore/agents/agent_components/state_transition.pycore/agents/agent_components/streaming.pycore/agents/agent_components/orchestrator/orchestrator.pycore/agents/agent_components/orchestrator/tool_dispatcher.pycore/agents/agent_components/orchestrator/usage_tracker.pycore/agents/resume/sanitize.pycore/agents/resume/sanitize_debug.py
Acceptance:
- All imports updated
ruff checkpasses- No import errors at runtime
Task 4: Delete dead code
Summary: Remove unused types from shared types layer Delete:
CommandContextfromtypes/dataclasses.pyProcessRequestCallbackfromtypes/callbacks.py
Acceptance:
- Dead code removed
- No references remain
ruff checkpasses
Task 5: Verify and update documentation
Summary: Run tests, update DEPENDENCY_MAP.md Files:
docs/architecture/DEPENDENCY_MAP.md
Acceptance:
uv run pytestpasses- DEPENDENCY_MAP.md reflects new structure
core → typesimport count reduced
Risks & Mitigations
| Risk | Impact | Likelihood | Mitigation | Trigger |
|---|---|---|---|---|
| Circular imports | High | Medium | Careful ordering in init.py | Import error on startup |
| Missed import | Medium | Low | grep for old import paths | Test failure |
| Type checker errors | Medium | Medium | Run mypy, use git commit -n if blocked |
mypy failure |
Test Strategy
- Run existing test suite:
uv run pytest - Manual verification:
python -c "from tunacode.core.types import AgentState" - No new tests needed (structural change only)
Tickets Created
| Ticket ID | Title | Priority | Status | Depends On |
|---|---|---|---|---|
| tun-3f92 | Create core/types/ directory structure | P1 | open | - |
| tun-979a | Move 9 core-specific types to core/types/ | P1 | open | tun-3f92 |
| tun-48fe | Update 17 core files to import from core/types/ | P1 | open | tun-979a |
| tun-f096 | Delete dead code (CommandContext, ProcessRequestCallback) | P2 | open | tun-48fe |
| tun-3cde | Verify tests and update DEPENDENCY_MAP.md | P2 | open | tun-48fe |
References
- Research:
memory-bank/research/2026-01-27_00-10-38_issue-311-core-types-layer-violation.md - Issue: https://github.com/alchemiststudiosDOTai/tunacode/issues/311
- Clean Architecture best practice: domain types live in domain layer