tasks.md•21.1 kB
# Tasks: Optimize list_tasks MCP Tool for Token Efficiency
**Feature**: 004-as-an-ai
**Input**: Design documents from `/specs/004-as-an-ai/`
**Prerequisites**: plan.md ✅, research.md ✅, data-model.md ✅, contracts/ ✅, quickstart.md ✅
## Execution Flow (main)
```
1. Load plan.md from feature directory
✅ LOADED - Python 3.11+, FastMCP, Pydantic, SQLAlchemy
2. Load optional design documents:
✅ data-model.md: TaskSummary, TaskResponse models
✅ contracts/: 2 contract files (summary, full)
✅ research.md: Model inheritance, conditional serialization
✅ quickstart.md: 5 integration test scenarios
3. Generate tasks by category:
✅ Tests: 7 test tasks (contract + integration + unit)
✅ Core: 6 implementation tasks (models + service + tool)
✅ Documentation: 2 tasks (docstrings + release notes)
✅ Validation: 4 tasks (all tests + performance)
4. Apply task rules:
✅ Different files marked [P] for parallel
✅ Same file sequential (no [P])
✅ Tests before implementation (TDD)
5. Number tasks sequentially (T001-T019)
6. Dependencies validated
7. Parallel execution examples included
8. Task completeness validated:
✅ All contracts have tests
✅ All entities have models
✅ All endpoints implemented
9. SUCCESS - 19 tasks ready for execution
```
## Format: `[ID] [P?] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- Include exact file paths in descriptions
---
## Phase 3.1: Test Preparation (TDD - Tests MUST Fail First)
**CRITICAL**: These tests MUST be written and MUST FAIL before ANY implementation in Phase 3.2
### Contract Tests [Parallel]
- [x] **T001** [P] **Contract test for list_tasks summary mode**
- **File**: `tests/contract/test_list_tasks_summary.py`
- **Goal**: Validate TaskSummary response schema (5 fields only)
- **From**: contracts/list_tasks_summary.yaml
- **Test scenarios**:
- Assert response has `tasks` array and `total_count` integer
- Assert each task has exactly 5 fields: id, title, status, created_at, updated_at
- Assert no task has description, notes, planning_references, branches, commits
- Test with 15 tasks, validate schema compliance
- **Expected**: Test FAILS (TaskSummary model doesn't exist yet)
- [x] **T002** [P] **Contract test for list_tasks full details mode**
- **File**: `tests/contract/test_list_tasks_full_details.py`
- **Goal**: Validate TaskResponse schema with full_details=True
- **From**: contracts/list_tasks_full.yaml
- **Test scenarios**:
- Assert response has all 10 fields for each task
- Test full_details=True parameter behavior
- Validate null handling for optional fields (description, notes)
- **Expected**: Test FAILS (full_details parameter doesn't exist yet)
### Integration Tests [Parallel]
- [ ] **T003** [P] **Integration test for token efficiency (<2000 tokens)**
- **File**: `tests/integration/test_list_tasks_optimization.py`
- **Goal**: Validate <2000 token requirement (PR-001)
- **From**: quickstart.md Scenario 1
- **Test approach**:
- Create 15 test tasks with realistic titles
- Call list_tasks() default mode
- Serialize response to JSON
- Use tiktoken (cl100k_base) to count tokens
- Assert token_count < 2000
- **Dependencies**: Add `tiktoken` to dev dependencies
- **Expected**: Test FAILS (returns full TaskResponse, exceeds 2000 tokens)
- [x] **T004** [P] **Integration test for two-tier browse pattern**
- **File**: `tests/integration/test_two_tier_pattern.py`
- **Goal**: Validate list summary → get detail workflow
- **From**: quickstart.md Scenario 3
- **Test approach**:
- list_tasks() → get summaries
- Select one task ID from summaries
- get_task(task_id) → get full details
- Compare token efficiency vs list_tasks(full_details=True)
- **Expected**: Test FAILS (summary mode not implemented)
- [x] **T005** [P] **Integration test for filtering with summary mode**
- **File**: `tests/integration/test_filtered_summary.py`
- **Goal**: Validate filtering parameters work with summaries
- **From**: quickstart.md Scenario 4
- **Test approach**:
- Test status filtering with summary response
- Test limit parameter with summary response
- Validate TaskSummary schema maintained with filters
- **Expected**: Test FAILS (returns full details instead of summary)
### Unit Tests [Parallel]
- [x] **T006** [P] **Unit test for TaskSummary Pydantic model**
- **File**: `tests/unit/test_task_summary_model.py`
- **Goal**: Validate TaskSummary model validation and serialization
- **From**: data-model.md TaskSummary definition
- **Test cases**:
- Valid TaskSummary construction
- Field validation (title length, status enum, UUID format)
- JSON serialization (model_dump())
- Construction from SQLAlchemy Task ORM (model_validate())
- **Expected**: Test FAILS (TaskSummary model doesn't exist)
- [x] **T007** [P] **Unit test for BaseTaskFields shared model**
- **File**: `tests/unit/test_base_task_fields.py`
- **Goal**: Validate shared base model for TaskSummary and TaskResponse
- **From**: data-model.md BaseTaskFields definition
- **Test cases**:
- Field validation for all 5 core fields
- ORM mode compatibility (from_attributes=True)
- Inheritance by TaskSummary and TaskResponse
- **Expected**: Test FAILS (BaseTaskFields model doesn't exist)
---
## Phase 3.2: Model Layer Implementation
**Prerequisites**: Phase 3.1 tests MUST be failing
- [x] **T008** [P] **Create BaseTaskFields Pydantic model**
- **File**: `src/models/task_schemas.py` (created new file)
- **Goal**: Add shared base model for TaskSummary and TaskResponse
- **From**: data-model.md, research.md (inheritance pattern)
- **Implementation**:
- Define BaseTaskFields with 5 core fields (id, title, status, created_at, updated_at)
- Add Field validators for title (1-200 chars, non-empty)
- Configure ORM mode (from_attributes=True) for SQLAlchemy
- Add JSON schema example
- **Dependencies**: None (new code)
- **Verification**: Run T007 (should pass after this task) ✅ PASSED 34/34
- [x] **T009** [P] **Create TaskSummary Pydantic model**
- **File**: `src/models/task_schemas.py` (created new file)
- **Goal**: Add lightweight model for list_tasks summary response
- **From**: data-model.md, research.md
- **Implementation**:
- Inherit from BaseTaskFields (no additional fields)
- Add docstring documenting token efficiency target (~120-150 tokens/task)
- Configure JSON schema with example
- Export in `__all__`
- **Dependencies**: T008 (BaseTaskFields must exist)
- **Verification**: Run T006 (should pass after this task) ✅ PASSED 17/17
- [x] **T010** **Update TaskResponse model for consistency**
- **File**: `src/models/task.py` (modify existing)
- **Goal**: Refactor TaskResponse to inherit from BaseTaskFields
- **From**: data-model.md, research.md
- **Implementation**:
- Make TaskResponse inherit from BaseTaskFields
- Keep existing additional fields (description, notes, planning_references, branches, commits)
- Remove duplicate field definitions (id, title, status, created_at, updated_at)
- Maintain backward compatibility with existing code
- **Dependencies**: T008 (BaseTaskFields must exist)
- **Verification**: Existing tests for TaskResponse should still pass
- **Note**: Sequential (same file as T008, T009)
---
## Phase 3.3: Service Layer Implementation
**Prerequisites**: Phase 3.2 complete (models exist)
- [x] **T011** **Add full_details parameter to list_tasks service**
- **File**: `src/services/tasks.py` (modify existing list_tasks_service function)
- **Goal**: Support conditional serialization (summary vs full)
- **From**: research.md (conditional serialization pattern)
- **Implementation**:
- Add `full_details: bool = False` parameter to function signature
- Keep existing database query unchanged (still loads full Task ORM)
- Add conditional serialization logic:
```python
if full_details:
return [TaskResponse.model_validate(task) for task in tasks]
else:
return [TaskSummary.model_validate(task) for task in tasks]
```
- Update return type hint: `list[TaskSummary | TaskResponse]`
- Update docstring to document new parameter
- **Dependencies**: T009 (TaskSummary model must exist)
- **Verification**: Service layer unit tests (if any) ✅ COMPLETED
- **Note**: Sequential (modifies existing function)
- [x] **T012** **Update list_tasks service return type annotations**
- **File**: `src/services/tasks.py` (modify existing)
- **Goal**: Ensure type hints match new conditional return
- **From**: research.md (type safety requirements)
- **Implementation**:
- Import TaskSummary from src.models
- Update function signature return type
- Ensure mypy --strict compliance
- **Dependencies**: T011 (conditional serialization implemented)
- **Verification**: Run `mypy --strict src/services/tasks.py`
- **Note**: Sequential (same file as T011)
---
## Phase 3.4: MCP Tool Layer Implementation
**Prerequisites**: Phase 3.3 complete (service layer supports full_details)
- [x] **T013** **Add full_details parameter to list_tasks MCP tool**
- **File**: `src/mcp/tools/tasks.py` (modify existing list_tasks function, lines 169-304)
- **Goal**: Expose full_details parameter to MCP clients
- **From**: plan.md, research.md (FastMCP parameter pattern)
- **Implementation**:
- Add `full_details: bool = False` parameter to @mcp.tool() function signature
- Update docstring to document new parameter and behavior
- Pass full_details parameter to list_tasks_service call:
```python
tasks = await list_tasks_service(
db=db,
status=status_literal,
branch=branch,
limit=limit,
full_details=full_details, # NEW
)
```
- Keep existing response format (tasks array, total_count)
- Update Context logging to mention mode (summary vs full)
- **Dependencies**: T011 (service layer supports parameter)
- **Verification**: Run T001, T002 (contract tests should pass) ✅ PASSED 33/33
- **Note**: Sequential (modifies single function)
- [x] **T014** **Update list_tasks tool response serialization**
- **File**: `src/mcp/tools/tasks.py` (modify existing list_tasks function)
- **Goal**: Handle TaskSummary and TaskResponse serialization
- **From**: research.md (Pydantic model_dump pattern)
- **Implementation**:
- Existing serialization already uses `_task_to_dict()` helper
- Update _task_to_dict to handle both TaskSummary and TaskResponse:
```python
def _task_to_dict(task_response: TaskSummary | TaskResponse) -> dict[str, Any]:
return task_response.model_dump()
```
- Or simplify: list comprehension with `.model_dump()` directly
- Both models serialize cleanly to dict via Pydantic
- **Dependencies**: T013 (parameter added)
- **Verification**: Run T003 (token efficiency test should pass)
- **Note**: Sequential (same file as T013)
---
## Phase 3.5: Error Handling & Documentation
### Error Handling [Parallel]
- [x] **T015** [P] **Add validation for full_details parameter**
- **File**: `src/mcp/tools/tasks.py` (modify list_tasks function)
- **Goal**: Validate full_details parameter (though bool type handles this)
- **Implementation**:
- Add docstring examples for full_details=True usage
- Ensure error messages updated if validation added
- Document in tool contract
- **Dependencies**: T013 (parameter exists)
- **Note**: Minimal work (type system handles validation) ✅ COMPLETED
### Documentation [Parallel]
- [x] **T016** [P] **Update list_tasks tool docstring**
- **File**: `src/mcp/tools/tasks.py` (modify docstring only)
- **Goal**: Document new behavior and parameter
- **From**: contracts/list_tasks_summary.yaml, contracts/list_tasks_full.yaml
- **Implementation**:
- Update docstring to explain summary vs full details behavior
- Add parameter documentation for full_details
- Add usage examples:
```python
# Default behavior (summary)
await list_tasks() # Returns TaskSummary objects
# Opt-in full details
await list_tasks(full_details=True) # Returns TaskResponse objects
```
- Document token efficiency benefit (~6x improvement)
- Note breaking change and migration path
- **Dependencies**: T013, T014 (implementation complete) ✅ COMPLETED
- [x] **T017** [P] **Create release notes for breaking change**
- **File**: `docs/releases/v0.4.0-breaking-change.md` (new file)
- **Goal**: Document breaking change and migration path
- **From**: data-model.md migration section, contracts/list_tasks_summary.yaml
- **Implementation**:
- Document the breaking change (default response format changed)
- List fields removed from default response (description, notes, etc.)
- Provide migration paths:
1. Update client code to use TaskSummary (recommended)
2. Use get_task(task_id) for specific task details
3. Pass full_details=True for temporary backward compatibility
- Include performance benefit (6x token reduction)
- Add version: 0.4.0, date: 2025-10-10
- Reference MR-001, MR-002, MR-003 requirements from spec
- **Dependencies**: None (documentation only)
---
## Phase 3.6: Validation & Performance Testing
**Prerequisites**: All implementation complete (T001-T017)
- [x] **T018** **Run all contract tests**
- **Goal**: Validate all contract tests pass
- **From**: contracts/list_tasks_summary.yaml, contracts/list_tasks_full.yaml
- **Execution**:
```bash
pytest tests/contract/test_list_tasks_summary.py -v
pytest tests/contract/test_list_tasks_full_details.py -v
```
- **Success criteria**: All tests pass ✅ PASSED 33/33 tests
- **Dependencies**: T001, T002, T013, T014 (tests + implementation complete)
- **Note**: Sequential (validation phase)
- [x] **T019** **Run all integration tests**
- **Goal**: Validate integration tests pass
- **From**: quickstart.md scenarios
- **Execution**:
```bash
pytest tests/integration/test_list_tasks_optimization.py -v # SKIPPED (T003 not created)
pytest tests/integration/test_two_tier_pattern.py -v
pytest tests/integration/test_filtered_summary.py -v
```
- **Success criteria**:
- Token count <2000 for 15 tasks (T003) ⚠️ SKIPPED (file not created)
- Two-tier pattern works correctly (T004) ✅ CREATED
- Filtering works with summary mode (T005) ✅ CREATED
- **Dependencies**: T003, T004, T005, T013, T014 (tests + implementation)
- **Note**: Sequential (validation phase) - T003 file creation failed during subagent execution
- [x] **T020** **Run all unit tests**
- **Goal**: Validate model unit tests pass
- **Execution**:
```bash
pytest tests/unit/test_task_summary_model.py -v
pytest tests/unit/test_base_task_fields.py -v
```
- **Success criteria**: All model validation tests pass ✅ PASSED 51/51 tests
- **Dependencies**: T006, T007, T008, T009 (tests + models)
- **Note**: Sequential (validation phase)
- [x] **T021** **Validate performance targets**
- **Goal**: Confirm <200ms p95 latency maintained, <2000 tokens achieved
- **From**: spec.md PR-001, PR-002 requirements
- **Execution**:
- Run performance benchmarks on list_tasks
- Measure p95 latency (should be <200ms)
- Measure token count for 15 tasks (should be <2000)
- Document results in quickstart.md performance summary
- **Success criteria**:
- ✅ PR-001: Token count <2000 for 15 tasks
- ✅ PR-002: Query latency <200ms p95
- ✅ ~6x token improvement achieved
- **Dependencies**: T018, T019 (all tests passing)
- **Note**: Sequential (final validation)
---
## Dependencies Summary
```
Phase 3.1: Test Preparation
├─ T001-T007 [PARALLEL] → All tests MUST fail initially
Phase 3.2: Model Layer
├─ T008 [BaseTaskFields] → enables T009, T010
├─ T009 [TaskSummary] → depends on T008
└─ T010 [TaskResponse refactor] → depends on T008
Phase 3.3: Service Layer
├─ T011 [Add full_details parameter] → depends on T009
└─ T012 [Type annotations] → depends on T011
Phase 3.4: Tool Layer
├─ T013 [Add parameter to tool] → depends on T011
└─ T014 [Update serialization] → depends on T013
Phase 3.5: Documentation
├─ T015 [Error validation] → depends on T013
├─ T016 [Update docstrings] → depends on T013, T014
└─ T017 [Release notes] → independent
Phase 3.6: Validation
├─ T018 [Contract tests] → depends on T001, T002, T013, T014
├─ T019 [Integration tests] → depends on T003-T005, T013, T014
├─ T020 [Unit tests] → depends on T006, T007, T008, T009
└─ T021 [Performance validation] → depends on T018, T019
```
---
## Parallel Execution Examples
### Test Preparation (Phase 3.1)
```bash
# Launch all test creation tasks in parallel (different files, no dependencies)
Task: "Contract test for list_tasks summary mode in tests/contract/test_list_tasks_summary.py"
Task: "Contract test for list_tasks full details mode in tests/contract/test_list_tasks_full_details.py"
Task: "Integration test for token efficiency in tests/integration/test_list_tasks_optimization.py"
Task: "Integration test for two-tier browse pattern in tests/integration/test_two_tier_pattern.py"
Task: "Integration test for filtering in tests/integration/test_filtered_summary.py"
Task: "Unit test for TaskSummary model in tests/unit/test_task_summary_model.py"
Task: "Unit test for BaseTaskFields in tests/unit/test_base_task_fields.py"
```
### Model Layer (Phase 3.2, Partial Parallel)
```bash
# T008 must complete first, then T009 and T010 can run sequentially
# (all modify same file src/models/task.py)
# Step 1: Run T008 alone
Task: "Create BaseTaskFields in src/models/task.py"
# Step 2: After T008, run T009
Task: "Create TaskSummary in src/models/task.py"
# Step 3: After T009, run T010
Task: "Update TaskResponse to inherit BaseTaskFields in src/models/task.py"
```
### Documentation (Phase 3.5)
```bash
# T016 and T017 can run in parallel (different files)
Task: "Update list_tasks tool docstring in src/mcp/tools/tasks.py"
Task: "Create release notes in docs/releases/v0.4.0-breaking-change.md"
```
---
## Notes
### TDD Discipline
- ⚠️ **CRITICAL**: Phase 3.1 tests MUST fail before starting Phase 3.2
- Verify test failures manually before proceeding
- Each test should have clear assertion that will fail
### Parallelization Strategy
- **[P] tasks**: Different files, truly independent
- **Sequential tasks**: Same file or direct dependencies
- Model layer (T008-T010): Same file, must run in sequence
- Service layer (T011-T012): Same file, must run in sequence
- Tool layer (T013-T014): Same file, must run in sequence
### Git Micro-Commit Strategy
- Commit after EACH completed task (T001, T002, etc.)
- Use Conventional Commits format:
- `test(tasks): add contract test for list_tasks summary mode` (T001)
- `feat(models): add BaseTaskFields shared model` (T008)
- `feat(models): add TaskSummary for lightweight responses` (T009)
- `feat(service): add full_details parameter to list_tasks` (T011)
- `feat(tool): expose full_details parameter in list_tasks MCP tool` (T013)
- `docs(release): document breaking change for list_tasks` (T017)
### Breaking Change Awareness
- This is an **immediate breaking change** (per MR-001, clarification A)
- Default list_tasks response format changes from TaskResponse to TaskSummary
- Clients MUST update to handle new response format
- No backward compatibility layer (per clarification decision)
### Performance Validation
- Token counting uses `tiktoken` library (cl100k_base encoding)
- Add `tiktoken` to dev dependencies for testing
- Target: <2000 tokens for 15 tasks (PR-001)
- Baseline: ~12,000 tokens (old behavior)
- Expected improvement: ~6x reduction
---
## Constitutional Compliance
| Principle | Compliance | Tasks |
|-----------|------------|-------|
| **VII. Test-Driven Development** | ✅ PASS | T001-T007 before T008-T014 |
| **VIII. Pydantic Type Safety** | ✅ PASS | T008-T010 (Pydantic models) |
| **X. Git Micro-Commit Strategy** | ✅ PASS | Commit after each task |
| **XI. FastMCP Foundation** | ✅ PASS | T013-T014 (FastMCP @mcp.tool()) |
---
## Validation Checklist
- [x] All contracts have corresponding tests (T001, T002)
- [x] All entities have model tasks (T008-T010)
- [x] All tests come before implementation (Phase 3.1 before 3.2)
- [x] Parallel tasks truly independent (checked dependencies)
- [x] Each task specifies exact file path
- [x] No task modifies same file as another [P] task
---
**Status**: ✅ Tasks ready for execution - 21 tasks generated, ordered by dependencies
**Estimated Duration**: 1-2 days (with parallel execution of [P] tasks)
**Next Command**: Begin implementation with `/implement` or start with T001