Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 162 additions & 36 deletions docs/specs/002-wishful-context/implementation-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,47 @@

*GATE: Read all files before starting implementation.*

**Current Status (2026-06-03 refresh)**:
- `wishful.evolve()` is implemented and exported.
- `wishful.context` is still unimplemented.
- 002 should finish with registered context available to `evolve()`,
`explore()`, and `wishful.static.*` / `wishful.dynamic.*` imports.
- This repo uses `AGENTS.md` as the live agent architecture/instructions file;
there is no `CLAUDE.md`.
- Always run project Python commands through `uv run`.

**Specification**:
- `docs/specs/002-wishful-context/product-requirements.md` - PRD
- `docs/specs/002-wishful-context/solution-design.md` - SDD

**Reference Implementation**:
- `src/wishful/types/registry.py` - Pattern to mirror exactly
- `src/wishful/types/__init__.py` - Export pattern
- `src/wishful/evolve/evolver.py` - Public evolve loop and mutation call site
- `src/wishful/evolve/mutation.py` - Prompt context builder to extend
- `src/wishful/explore/explorer.py` - String-path variant generation
- `src/wishful/core/loader.py` - Static/dynamic generation
- `src/wishful/config.py` - Settings and environment variables
- `src/wishful/cache/manager.py` - Static cache behavior

**Key Design Decisions**:
1. Mirror `@wishful.type` pattern exactly
2. Use `for_=` parameter name
3. Global registry only (no scopes)
4. List targets register for each with priority order
4. List targets register the same provider for each target; priority for a target is registration order
5. Registered context applies to evolve, explore, static, and dynamic by default
6. Static imports stay cache-first by default; context-change invalidation is opt-in

**Commands**:
```bash
uv run pytest tests/test_context.py -v # Context tests
uv run pytest tests/test_evolve.py -v # Verify evolve still works
uv run mypy src/wishful/context/ # Type check
uv run pytest tests/test_explore.py -v # Verify explore context integration
uv run pytest tests/test_import_hook.py -v # Verify static import behavior
uv run pytest tests/test_namespaces.py -v # Verify dynamic behavior
uv run pytest tests/test_config.py -v # Verify settings
uv run mypy src/wishful/context/ src/wishful/evolve/ # Type check
uv run python -c "from wishful import context, get_context_for; print('OK')"
```

---
Expand All @@ -61,6 +83,7 @@ uv run mypy src/wishful/context/ # Type check
- [ ] T1.2.7 Test: `test_clear_registry`
- [ ] T1.2.8 Test: `test_multiple_contexts_same_target`
- [ ] T1.2.9 Test: `test_docstring_extraction`
- [ ] T1.2.10 Test: `test_rejects_callable_instance_target_without_stable_key`

- [ ] T1.3 Implement `[activity: component-development]`
- [ ] T1.3.1 Create `src/wishful/context/__init__.py` with exports
Expand All @@ -71,31 +94,55 @@ uv run mypy src/wishful/context/ # Type check
- [ ] `context(for_=)` decorator
- [ ] `get_context_for(target)` function
- [ ] `clear_context_registry()` function
- [ ] T1.3.3 Create `src/wishful/context/formatting.py` with:
- [ ] `build_context_block(targets, surface, base_context=None)`
- [ ] target expansion for exact vs module fallback
- [ ] max-entry limiting
- [ ] surface enable/disable checks

- [ ] T1.4 Validate `[activity: run-tests]`
- [ ] T1.4.1 Run `uv run pytest tests/test_context.py -v`
- [ ] T1.4.2 Run `uv run mypy src/wishful/context/`
- [ ] T1.4.3 Verify import: `python -c "from wishful.context import context, get_context_for"`
- [ ] T1.4.3 Verify import: `uv run python -c "from wishful.context import context, get_context_for"`

---

### Phase 2: Public API Export
### Phase 2: Public API and Settings

- [ ] T2 Phase 2: Wishful Package Integration `[component: wishful]`
- [ ] T2 Phase 2: Wishful Package Integration and Settings `[component: wishful]`

- [ ] T2.1 Prime Context
- [ ] T2.1.1 Read `src/wishful/__init__.py` for export pattern
- [ ] T2.1.2 Read `src/wishful/config.py` for settings pattern

- [ ] T2.2 Write Tests `[activity: test-execution]`
- [ ] T2.2.1 Test: `test_context_importable_from_wishful`
- [ ] T2.2.2 Test: `test_get_context_for_importable_from_wishful`
- [ ] T2.2.3 Test: context settings default values
- [ ] T2.2.4 Test: `configure()` updates context settings
- [ ] T2.2.5 Test: environment variables populate context settings
- [ ] T2.2.6 Test: `reset_defaults()` restores context settings

- [ ] T2.3 Implement `[activity: component-development]`
- [ ] T2.3.1 Modify `src/wishful/__init__.py` to export `context`, `get_context_for`
- [ ] T2.3.2 Add settings:
- [ ] `context_enabled: bool = True`
- [ ] `context_surfaces: tuple[str, ...] = ("evolve", "explore", "static", "dynamic")`
- [ ] `context_lookup: str = "exact_then_module"`
- [ ] `context_static_cache_policy: str = "cache_first"`
- [ ] `context_max_entries: int = 8`
- [ ] T2.3.3 Add env vars:
- [ ] `WISHFUL_CONTEXT`
- [ ] `WISHFUL_CONTEXT_SURFACES`
- [ ] `WISHFUL_CONTEXT_LOOKUP`
- [ ] `WISHFUL_CONTEXT_STATIC_CACHE_POLICY`
- [ ] `WISHFUL_CONTEXT_MAX_ENTRIES`
- [ ] T2.3.4 Update `configure()`, `Settings.copy()`, and `reset_defaults()`

- [ ] T2.4 Validate `[activity: run-tests]`
- [ ] T2.4.1 Run `python -c "from wishful import context, get_context_for; print('OK')"`
- [ ] T2.4.2 Run full test suite: `uv run pytest tests/ -v`
- [ ] T2.4.1 Run `uv run python -c "from wishful import context, get_context_for; print('OK')"`
- [ ] T2.4.2 Run `uv run pytest tests/test_config.py -v`
- [ ] T2.4.3 Run full test suite: `uv run pytest tests/ -v`

---

Expand All @@ -105,17 +152,21 @@ uv run mypy src/wishful/context/ # Type check

- [ ] T3.1 Prime Context
- [ ] T3.1.1 Read `src/wishful/evolve/mutation.py` current implementation
- [ ] T3.1.2 Read SDD Integration section `[ref: SDD; lines: 192-227]`
- [ ] T3.1.2 Read `src/wishful/evolve/evolver.py` current implementation
- [ ] T3.1.3 Read SDD Integration section

- [ ] T3.2 Write Tests `[activity: test-execution]`
- [ ] T3.2.1 Test: `test_build_evolution_context_includes_registered_context`
- [ ] T3.2.2 Test: `test_build_evolution_context_no_context_registered`
- [ ] T3.2.3 Test: `test_context_docstring_included_in_prompt`
- [ ] T3.2.4 Test: public `evolve()` passes the original target function into mutation context lookup

- [ ] T3.3 Implement `[activity: component-development]`
- [ ] T3.3.1 Add `target_function: Callable | None = None` param to `_build_evolution_context()`
- [ ] T3.3.2 Add context lookup and formatting logic
- [ ] T3.3.3 Update `mutate_with_llm()` to pass target function
- [ ] T3.3.3 Add `target_function: Callable | None = None` param to `mutate_with_llm()`
- [ ] T3.3.4 Update `mutate_with_llm()` to pass target function to `_build_evolution_context()`
- [ ] T3.3.5 Update `evolve()` to call `mutate_with_llm(..., target_function=fn)` with the original target function

- [ ] T3.4 Validate `[activity: run-tests]`
- [ ] T3.4.1 Run `uv run pytest tests/test_evolve.py -v`
Expand All @@ -124,47 +175,115 @@ uv run mypy src/wishful/context/ # Type check

---

### Phase 4: Documentation & Spec Updates
### Phase 4: Explore Integration

- [ ] T4 Phase 4: Explore Integration `[component: explore]`

- [ ] T4.1 Prime Context
- [ ] T4.1.1 Read `src/wishful/explore/explorer.py`
- [ ] T4.1.2 Read SDD Explore Integration section

- [ ] T4.2 Write Tests `[activity: test-execution]`
- [ ] T4.2.1 Test: `explore()` includes exact target registered context
- [ ] T4.2.2 Test: module-level context is included when `context_lookup="exact_then_module"`
- [ ] T4.2.3 Test: module-level context is excluded when `context_lookup="exact"`
- [ ] T4.2.4 Test: explore skips context when `"explore"` is not in `context_surfaces`
- [ ] T4.2.5 Test: `test` and `benchmark` callables are not automatically embedded

- [ ] T4.3 Implement `[activity: component-development]`
- [ ] T4.3.1 Build exact explore target from `module_name` and `function_name`
- [ ] T4.3.2 Pass `build_context_block(..., surface="explore")` result to `agenerate_module_code(...)`
- [ ] T4.3.3 Preserve winner caching behavior

- [ ] T4.4 Validate `[activity: run-tests]`
- [ ] T4.4.1 Run `uv run pytest tests/test_explore.py -v`
- [ ] T4.4.2 Run `uv run pytest tests/test_context.py -v`

---

### Phase 5: Static/Dynamic Import Integration

- [ ] T5 Phase 5: Static/Dynamic Import Integration `[component: import-hook]`

- [ ] T5.1 Prime Context
- [ ] T5.1.1 Read `src/wishful/core/loader.py`
- [ ] T5.1.2 Read `src/wishful/core/discovery.py`
- [ ] T5.1.3 Read `src/wishful/cache/manager.py`
- [ ] T5.1.4 Read SDD Static/Dynamic Integration section

- [ ] T5.2 Write Tests `[activity: test-execution]`
- [ ] T5.2.1 Test: static cache miss includes registered exact function context
- [ ] T5.2.2 Test: static cache miss merges registered context with discovered import-site context
- [ ] T5.2.3 Test: existing static cache wins when `context_static_cache_policy="cache_first"`
- [ ] T5.2.4 Test: static cache regenerates on context fingerprint change when `context_static_cache_policy="invalidate_on_change"`
- [ ] T5.2.5 Test: static skips registered context when `context_static_cache_policy="ignore"`
- [ ] T5.2.6 Test: dynamic generation includes registered context on each regeneration
- [ ] T5.2.7 Test: multiple requested symbols include symbol-specific context
- [ ] T5.2.8 Test: module-level context is included/excluded according to `context_lookup`

- [ ] T5.3 Implement `[activity: component-development]`
- [ ] T5.3.1 Add loader helper to build context targets from `fullname` and requested functions
- [ ] T5.3.2 Merge registered context into `context.context` before `generate_module_code(...)`
- [ ] T5.3.3 Preserve static `cache_first` path before generation
- [ ] T5.3.4 Add optional context fingerprint metadata for `invalidate_on_change`
- [ ] T5.3.5 Ensure dynamic mode includes registered context on proxy/runtime regeneration

- [ ] T5.4 Validate `[activity: run-tests]`
- [ ] T5.4.1 Run `uv run pytest tests/test_import_hook.py -v`
- [ ] T5.4.2 Run `uv run pytest tests/test_namespaces.py -v`
- [ ] T5.4.3 Run `uv run pytest tests/test_context.py -v`

---

### Phase 6: Documentation & Spec Updates

- [ ] T4 Phase 4: Update 001-wishful-evolve Documentation `[component: docs]`
- [ ] T6 Phase 6: Documentation, Examples, and Spec Updates `[component: docs]`

- [ ] T4.1 Update Evolve Implementation Plan
- [ ] T4.1.1 Add note about `@wishful.context` integration in `docs/specs/001-wishful-evolve/implementation-plan.md`
- [ ] T4.1.2 Update Phase 3 (Core Evolver) to pass `target_function` to mutation
- [ ] T6.1 Update Evolve Implementation Plan
- [ ] T6.1.1 Add note about `@wishful.context` integration in `docs/specs/001-wishful-evolve/implementation-plan.md`
- [ ] T6.1.2 Update Phase 3 (Core Evolver) to pass `target_function` to mutation

- [ ] T4.2 Update Evolve Design Docs
- [ ] T4.2.1 Add context integration section to `docs/specs/001-wishful-evolve/implementation-plan.md`
- [ ] T4.2.2 Add context follow-up notes to `docs/specs/003-wishful-code-search-workbench/concept-plan.md`
- [ ] T6.2 Update Workbench Direction Docs
- [ ] T6.2.1 Add context integration section to `docs/specs/003-wishful-code-search-workbench/concept-plan.md`
- [ ] T6.2.2 Document which tricky behavior is configurable

- [ ] T4.3 Update CLAUDE.md
- [ ] T4.3.1 Add `wishful.context` to architecture section
- [ ] T4.3.2 Update session history
- [ ] T6.3 Update AGENTS.md
- [ ] T6.3.1 Add `wishful.context` to architecture section
- [ ] T6.3.2 Update repository layout and test list if needed

- [ ] T4.4 Create Tryout Scripts
- [ ] T4.4.1 Create `examples/15_context_basic.py`
- [ ] T4.4.2 Create `examples/16_context_with_evolve.py`
- [ ] T4.4.3 Document context examples in `README.md`
- [ ] T6.4 Create Examples
- [ ] T6.4.1 Create `examples/15_context_basic.py`
- [ ] T6.4.2 Create `examples/16_context_with_evolve.py`
- [ ] T6.4.3 Create `examples/17_context_with_explore.py`
- [ ] T6.4.4 Create `examples/18_context_with_static_import.py`
- [ ] T6.4.5 Document context examples and settings in `README.md`

---

### Phase 5: Final Validation
### Phase 7: Final Validation

- [ ] T5 Integration & End-to-End Validation
- [ ] T7 Integration & End-to-End Validation

- [ ] T5.1 All unit tests passing: `uv run pytest tests/test_context.py -v`
- [ ] T5.2 All evolve tests passing: `uv run pytest tests/test_evolve.py -v`
- [ ] T5.3 Full test suite passing: `uv run pytest tests/ -v`
- [ ] T5.4 Type checking passes: `uv run mypy src/wishful/context/ src/wishful/evolve/`
- [ ] T5.5 Import verification: `from wishful import context, get_context_for`
- [ ] T5.6 Test coverage ≥90% for new code
- [ ] T5.7 Tryout scripts run successfully
- [ ] T5.8 PRD acceptance criteria verified:
- [ ] T7.1 All unit tests passing: `uv run pytest tests/test_context.py -v`
- [ ] T7.2 All evolve tests passing: `uv run pytest tests/test_evolve.py -v`
- [ ] T7.3 All explore tests passing: `uv run pytest tests/test_explore.py -v`
- [ ] T7.4 Import-hook tests passing: `uv run pytest tests/test_import_hook.py tests/test_namespaces.py -v`
- [ ] T7.5 Full test suite passing: `uv run pytest tests/ -v`
- [ ] T7.6 Type checking passes: `uv run mypy src/wishful/context/ src/wishful/evolve/`
- [ ] T7.7 Import verification: `uv run python -c "from wishful import context, get_context_for; print('OK')"`
- [ ] T7.8 Test coverage ≥90% for new code
- [ ] T7.9 Tryout scripts run successfully
- [ ] T7.10 PRD acceptance criteria verified:
- [ ] `@wishful.context(for_=target)` works
- [ ] Supports function references
- [ ] Supports string paths
- [ ] Supports list of targets
- [ ] `get_context_for()` returns source + docstring
- [ ] Integrates with `_build_evolution_context()`
- [ ] Integrates with `explore()`
- [ ] Integrates with static import generation
- [ ] Integrates with dynamic import generation
- [ ] Context settings work through `configure()` and env vars

---

Expand All @@ -174,7 +293,11 @@ uv run mypy src/wishful/context/ # Type check
- [ ] Test coverage ≥90% for `src/wishful/context/`
- [ ] `wishful.context` importable from main package
- [ ] Works with evolve's `_build_evolution_context()`
- [ ] Documentation updated (CLAUDE.md, evolve docs)
- [ ] Works with explore variant generation
- [ ] Works with static and dynamic import generation
- [ ] Static cache remains cache-first by default
- [ ] Context settings documented and tested
- [ ] Documentation updated (AGENTS.md, README, evolve/workbench docs)
- [ ] Tryout scripts demonstrate usage
- [ ] Type hints complete, mypy passes

Expand All @@ -185,5 +308,8 @@ uv run mypy src/wishful/context/ # Type check
| Risk | Mitigation |
|------|------------|
| Circular import with evolve | Lazy import in `_build_evolution_context()` |
| Source extraction fails | Fallback to `repr()` with warning |
| Source extraction fails | Store a descriptive stub string with provider name/module so prompts remain readable |
| Target resolution ambiguous | Clear error messages, documentation |
| Context bloats prompts | `context_max_entries` and exact-only lookup setting |
| Static cache surprises users | Default `cache_first`, explicit `invalidate_on_change` opt-in |
| Context changes do not affect existing cached static modules | Document default clearly and offer `regenerate()` or `invalidate_on_change` |
Loading
Loading