---
phase: 01-config-and-command-foundation
plan: 03
type: execute
wave: 3
depends_on:
  - 01
  - 02
files_modified:
  - pipeline/worker/scripts/literature_pipeline.py
  - skills/literature-qa/scripts/ld_deep.py
  - setup_wizard.py
  - scripts/validate_setup.py
  - tests/test_legacy_worker_compat.py
  - tests/test_ld_deep_config.py
autonomous: true
requirements:
  - CONF-03
  - CONF-04
  - CMD-02
  - DEEP-02
must_haves:
  truths:
    - "Legacy direct worker invocation still works with `python ...literature_pipeline.py --vault <vault> status`."
    - "Worker path construction and /LD-deep prepare path construction use the same resolver contract."
    - "Setup deployment accounts for the resolver package when worker and skill scripts are copied into a vault."
  artifacts:
    - path: "pipeline/worker/scripts/literature_pipeline.py"
      provides: "Legacy worker entry point backed by shared resolver"
    - path: "skills/literature-qa/scripts/ld_deep.py"
      provides: "/LD-deep helper backed by shared resolver"
    - path: "setup_wizard.py"
      provides: "Deployment copy/install logic for resolver availability"
    - path: "scripts/validate_setup.py"
      provides: "Validation config loading via shared resolver"
  key_links:
    - from: "pipeline/worker/scripts/literature_pipeline.py"
      to: "paperforge.config"
      via: "load_vault_config/pipeline_paths wrapper"
      pattern: "paperforge.config"
    - from: "skills/literature-qa/scripts/ld_deep.py"
      to: "paperforge.config"
      via: "_load_vault_config/_paperforge_paths wrapper"
      pattern: "paperforge.config"
    - from: "setup_wizard.py"
      to: "paperforge"
      via: "copy package or install-aware deployment"
      pattern: "paperforge"
---

<objective>
Wire existing worker, agent, setup, and validation code to the shared resolver without breaking legacy invocation.

Purpose: CONF-03 and DEEP-02 require more than a new module; the current worker and `/LD-deep` scripts must actually consume the same config/path contract.
Output: Compatibility wrappers, copied-install handling, and tests for direct worker and `/LD-deep` path behavior.
</objective>

<execution_context>
@C:/Users/Lin/.codex/get-shit-done/workflows/execute-plan.md
@C:/Users/Lin/.codex/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/REQUIREMENTS.md
@.planning/phases/01-config-and-command-foundation/01-CONTEXT.md
@.planning/phases/01-config-and-command-foundation/01-RESEARCH.md
@paperforge/config.py
@paperforge/cli.py
@pipeline/worker/scripts/literature_pipeline.py
@skills/literature-qa/scripts/ld_deep.py
@setup_wizard.py
@scripts/validate_setup.py

<interfaces>
Preserve these public function names for legacy callers:
```python
# pipeline/worker/scripts/literature_pipeline.py
def load_vault_config(vault: Path) -> dict:
def pipeline_paths(vault: Path) -> dict[str, Path]:
def main() -> int:

# skills/literature-qa/scripts/ld_deep.py
def _load_vault_config(vault: Path) -> dict:
def _paperforge_paths(vault: Path) -> dict[str, Path]:
def prepare_deep_reading(vault: Path, zotero_key: str, force: bool = False) -> dict:
```
</interfaces>
</context>

<tasks>

<task type="auto" tdd="true">
  <name>Task 1: Add compatibility tests for worker and /LD-deep path resolution</name>
  <files>tests/test_legacy_worker_compat.py, tests/test_ld_deep_config.py</files>
  <read_first>
    - `paperforge/config.py`
    - `pipeline/worker/scripts/literature_pipeline.py`
    - `skills/literature-qa/scripts/ld_deep.py`
    - `setup_wizard.py`
    - `scripts/validate_setup.py`
  </read_first>
  <behavior>
    - `literature_pipeline.load_vault_config(tmp_vault)` matches `paperforge.config.load_vault_config(tmp_vault)` for defaults, nested `vault_config`, top-level keys, and environment overrides.
    - `literature_pipeline.pipeline_paths(tmp_vault)` includes existing worker keys (`pipeline`, `exports`, `library_records`, `ocr`, `literature`, `bases`) and returns values derived from shared resolver.
    - Running the direct worker status path in a fixture vault via subprocess still exits without import errors: `python pipeline/worker/scripts/literature_pipeline.py --vault <tmp_vault> status`.
    - `ld_deep._paperforge_paths(tmp_vault)` returns `ocr`, `records`, and `literature` values matching `paperforge_paths()` for a custom `paperforge.json`.
  </behavior>
  <action>Create tests that build temporary vaults with `paperforge.json`, minimal PaperForge directories, and no real OCR jobs. Use subprocess only for the legacy `status` smoke test; keep other tests as direct imports. For env override assertions, use pytest `monkeypatch.setenv("PAPERFORGE_SYSTEM_DIR", "EnvSystem")` and clear it after the test. Do not test `ocr doctor` or PDF path resolution; those are deferred.</action>
  <verify>
    <automated>python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py -q</automated>
  </verify>
  <acceptance_criteria>
    - `rg -n "literature_pipeline.py --vault|_paperforge_paths|PAPERFORGE_SYSTEM_DIR|load_vault_config" tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py` confirms legacy and agent coverage.
    - `python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py -q` passes after Task 2.
  </acceptance_criteria>
  <done>Tests prove direct worker compatibility (CMD-02) and `/LD-deep` shared path resolution (DEEP-02).</done>
</task>

<task type="auto" tdd="true">
  <name>Task 2: Replace duplicated resolver logic with shared wrappers</name>
  <files>pipeline/worker/scripts/literature_pipeline.py, skills/literature-qa/scripts/ld_deep.py, scripts/validate_setup.py, tests/test_legacy_worker_compat.py, tests/test_ld_deep_config.py</files>
  <read_first>
    - `tests/test_legacy_worker_compat.py`
    - `tests/test_ld_deep_config.py`
    - `paperforge/config.py`
    - `pipeline/worker/scripts/literature_pipeline.py`
    - `skills/literature-qa/scripts/ld_deep.py`
    - `scripts/validate_setup.py`
  </read_first>
  <behavior>
    - Existing names `load_vault_config()` and `pipeline_paths()` remain available in `literature_pipeline.py`.
    - Existing names `_load_vault_config()` and `_paperforge_paths()` remain available in `ld_deep.py`.
    - Worker and `/LD-deep` wrappers import `paperforge.config` first and fail with an actionable import message only if neither package nor copied fallback is available.
    - `scripts/validate_setup.py` reads `PAPERFORGE_VAULT` before legacy `VAULT_PATH` and uses `paperforge.config.load_vault_config()`.
  </behavior>
  <action>In `literature_pipeline.py`, replace the body of `load_vault_config(vault)` with a wrapper around `paperforge.config.load_vault_config(vault)` and rebuild `pipeline_paths(vault)` from `paperforge.config.paperforge_paths(vault)` plus the existing worker-only keys (`candidates`, `candidate_inbox`, `candidate_archive`, `search_tasks`, `search_archive`, `search_results`, `harvest_root`, `records`, `review`, `config`, `queue`, `log`, `bridge_config`, `bridge_config_sample`, `index`, `ocr_queue`). In `ld_deep.py`, replace `_load_vault_config()` and `_paperforge_paths()` with wrappers around the same resolver, returning existing keys `ocr`, `records`, and `literature`. In `scripts/validate_setup.py`, import the shared resolver and use `PAPERFORGE_VAULT` first, then `VAULT_PATH`, then `.`. Keep `--vault` required for direct `literature_pipeline.py` CLI per CMD-02.</action>
  <verify>
    <automated>python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py tests/test_config.py -q</automated>
    <automated>python pipeline/worker/scripts/literature_pipeline.py --vault . status</automated>
  </verify>
  <acceptance_criteria>
    - `rg -n "from paperforge.config import|paperforge_paths|PAPERFORGE_VAULT|VAULT_PATH" pipeline/worker/scripts/literature_pipeline.py skills/literature-qa/scripts/ld_deep.py scripts/validate_setup.py` confirms shared resolver wiring and env compatibility.
    - `python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py tests/test_config.py -q` passes.
    - `python pipeline/worker/scripts/literature_pipeline.py --vault . status` exits 0 in the repo fixture.
  </acceptance_criteria>
  <done>Worker, `/LD-deep`, and validation config loading use the same resolver while preserving direct legacy invocation.</done>
</task>

<task type="auto">
  <name>Task 3: Deploy resolver package through setup wizard</name>
  <files>setup_wizard.py</files>
  <read_first>
    - `setup_wizard.py`
    - `paperforge/config.py`
    - `.planning/phases/01-config-and-command-foundation/01-RESEARCH.md`
  </read_first>
  <action>Update `setup_wizard.py` deployment logic near the existing worker and `ld_deep.py` copy operations so installed vaults can import `paperforge`. Copy the source repo `paperforge/` directory into `<system_dir>/PaperForge/worker/paperforge/` and into `<skill_dir>/literature-qa/paperforge/`, or add a tested package-install path if the wizard already performs pip installation. Keep existing copied file locations unchanged: `literature_pipeline.py` stays under `<system_dir>/PaperForge/worker/scripts/`, and `ld_deep.py` stays under `<skill_dir>/literature-qa/scripts/`. Do not overwrite user `AGENTS.md` beyond existing wizard behavior.</action>
  <verify>
    <automated>python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py -q</automated>
  </verify>
  <acceptance_criteria>
    - `rg -n "paperforge|shutil.copytree|worker/scripts|literature-qa" setup_wizard.py` confirms setup copies or installs the resolver package.
    - Existing copy targets for `literature_pipeline.py` and `ld_deep.py` remain present.
    - `python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py -q` passes.
  </acceptance_criteria>
  <done>Copied installations have access to `paperforge` without changing legacy script locations.</done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| copied package -> worker runtime | Setup copies executable Python code into a user vault. |
| env/config -> validation output | Validation reports local path status from user-controlled config. |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-01-05 | Tampering | `setup_wizard.py` copy logic | mitigate | Copy only the local `paperforge` package directory; do not download or execute remote code during Phase 1 setup changes. |
| T-01-06 | Repudiation | legacy worker status | accept | Phase 1 only preserves local status behavior; detailed audit logging is outside this phase. |
</threat_model>

<verification>
Run `python -m pytest tests/test_legacy_worker_compat.py tests/test_ld_deep_config.py tests/test_config.py -q` and `python pipeline/worker/scripts/literature_pipeline.py --vault . status`.
</verification>

<success_criteria>
The resolver is no longer theoretical: worker, `/LD-deep`, setup deployment, and validation all consume or deploy the same config contract.
</success_criteria>

<output>
After completion, create `.planning/phases/01-config-and-command-foundation/01-config-and-command-foundation-03-SUMMARY.md`
</output>
