---
phase: 06-setup-cli-diagnostics-consistency
plan: '02'
type: execute
wave: 2
depends_on:
  - '01'
files_modified:
  - pipeline/worker/scripts/literature_pipeline.py
  - setup_wizard.py
  - paperforge/cli.py
  - paperforge/config.py
autonomous: true
requirements:
  - SETUP-01
  - SETUP-02
  - SETUP-04
  - DIAG-01
  - DIAG-02
  - DIAG-03

must_haves:
  truths:
    - `python setup_wizard.py --vault <path>` pre-fills the vault path in the UI
    - `paperforge doctor` validates all *.json exports, not only library.json
    - Doctor reports worker_script path via same resolver as `paperforge paths --json`
    - PADDLEOCR_API_TOKEN is consistent across setup, worker, and doctor
  artifacts:
    - path: pipeline/worker/scripts/literature_pipeline.py
      provides: run_doctor iterates over *.json exports
      contains: glob("*.json")
    - path: setup_wizard.py
      provides: VaultStep receives vault from app, Input prefilled
      contains: VaultStep.*value
    - path: paperforge/config.py
      provides: paperforge_paths() returns worker_script path
      contains: paperforge_paths
  key_links:
    - from: run_doctor in literature_pipeline.py
      to: exports/*.json
      via: exports_dir.glob("*.json")
      pattern: glob.*\.json
    - from: setup_wizard.py VaultStep
      to: SetupWizardApp
      via: app.vault passed to step
      pattern: VaultStep.*vault
---

<objective>
Fix doctor export validation (per-domain *.json), vault prefilling in setup wizard, and ensure doctor uses consistent path resolver. These tasks have dependencies on understanding existing patterns.
</objective>

<context>
@.planning/phases/06-setup-cli-diagnostics-consistency/06-CONTEXT.md
@.planning/ROADMAP.md
@.planning/REQUIREMENTS.md
@.planning/STATE.md

From 06-CONTEXT.md (key locked decisions):
- D-07-D-09: Doctor validates all *.json files, not only library.json
- D-13-D-15: VaultStep needs vault passed from SetupWizardApp.__init__
- D-18-D-19: Doctor reports worker_script via paperforge_paths() resolver
- D-04-D-06: PADDLEOCR_API_TOKEN is canonical env var
</context>

<tasks>

<task type="auto">
  <name>Task 1: Fix run_doctor to validate all *.json exports (DIAG-01)</name>
  <files>pipeline/worker/scripts/literature_pipeline.py</files>
  <read_first>
    - pipeline/worker/scripts/literature_pipeline.py (around line 2910 for run_doctor export check)
    - paperforge/config.py (lines 208-276 for paperforge_paths)
  </read_first>
  <action>
    In `pipeline/worker/scripts/literature_pipeline.py`, find the run_doctor function (around line 2910).

    Current code checks for single library.json:
    ```python
    # Something like:
    if not (exports_dir / "library.json").exists():
        issues.append("library.json not found")
    ```

    Replace with glob-based validation that checks all *.json files:
    ```python
    json_files = list(exports_dir.glob("*.json"))
    if not json_files:
        issues.append(
            f"No JSON export files found in {exports_dir}. "
            "Run selection-sync first to generate export files."
        )
    # Don't require library.json specifically - any *.json is valid
    ```

    Also verify that the env var read uses PADDLEOCR_API_TOKEN (should already be correct per D-05, but confirm).
  </action>
  <verify>
    <automated>grep -n "glob.*\.json" pipeline/worker/scripts/literature_pipeline.py && echo "PASS: glob pattern found"</automated>
  </verify>
  <done>
    run_doctor validates all *.json exports under exports directory, not only library.json
  </done>
  <acceptance_criteria>
    - grep finds "glob" in literature_pipeline.py around run_doctor
    - No code requires "library.json" specifically as sole valid export
    - Context: D-07, D-08, D-09 from CONTEXT.md
  </acceptance_criteria>
</task>

<task type="auto">
  <name>Task 2: Prefill VaultStep Input from --vault argument (SETUP-01, SETUP-02)</name>
  <files>setup_wizard.py</files>
  <read_first>
    - setup_wizard.py (around lines 486-535 for VaultStep, around lines ~100 for SetupWizardApp.__init__)
  </read_first>
  <action>
    In `setup_wizard.py`, modify SetupWizardApp to pass vault to VaultStep.

    1. In SetupWizardApp.__init__ (around line 100), store vault parameter:
    ```python
    def __init__(self, vault: str = None, ...):
        self.vault = vault or os.environ.get("PAPERFORGE_VAULT", "")
    ```

    2. In VaultStep (around line 486-535), modify to accept and use vault:
    - If VaultStep receives vault via app.state or similar, use it to prefill Input
    - The Input widget should have value=app.vault (or equivalent)

    Current VaultStep compose (simplified):
    ```python
    def compose(self) -> ComposeResult:
        with container:
            yield Input(placeholder="Vault path")
    ```

    Modified:
    ```python
    def compose(self) -> ComposeResult:
        vault = getattr(self.app, 'vault', '')
        yield Input(value=vault, placeholder="Vault path")
    ```

    3. Ensure SetupWizardApp.__init__ calls VaultStep with vault context.

    NOTE: ProgressBar "stall" feeling is likely terminal display, not missing progress - per D-15. ProgressBar exists and advances on step transitions.
  </action>
  <verify>
    <automated>grep -n "value=vault\|value=self.vault" setup_wizard.py && echo "PASS: vault prefill found"</automated>
  </verify>
  <done>
    Running `python setup_wizard.py --vault <path>` prefills the vault path in the UI Input widget
  </done>
  <acceptance_criteria>
    - grep finds "value=" in VaultStep Input creation
    - VaultStep.compose yields Input with value set from app.vault or similar
    - Context: D-13, D-14, D-15 from CONTEXT.md
  </acceptance_criteria>
</task>

<task type="auto">
  <name>Task 3: Doctor uses paperforge_paths() for worker_script reporting (DIAG-03)</name>
  <files>
    - paperforge/ocr_diagnostics.py
    - paperforge/config.py
  </files>
  <read_first>
    - paperforge/ocr_diagnostics.py (lines 1-50 for imports, around line 28 for PADDLEOCR_API_TOKEN)
    - paperforge/config.py (lines 208-276 for paperforge_paths function)
  </read_first>
  <action>
    In `paperforge/ocr_diagnostics.py`, modify doctor to use paperforge_paths() resolver for worker_script path reporting instead of hardcoding.

    1. Import paperforge_paths at top:
    ```python
    from paperforge.config import paperforge_paths
    ```

    2. In doctor output/reporting section, use paperforge_paths() to get worker_script:
    ```python
    paths = paperforge_paths()
    worker_script = paths.get("worker_script", "not found")
    print(f"Worker script: {worker_script}")
    ```

    3. Also verify PADDLEOCR_API_TOKEN is used consistently (check line ~28 reads this correctly, not TOKEN or KEY).

    Current: `os.environ.get("PADDLEOCR_API_TOKEN")` or similar - should already be correct per D-04-D-06.

    4. If doctor has hardcoded paths, replace with paperforge_paths() calls.
  </action>
  <verify>
    <automated>grep -n "paperforge_paths" paperforge/ocr_diagnostics.py && echo "PASS: paperforge_paths used"</automated>
  </verify>
  <done>
    Doctor reports worker_script path via same resolver contract as `paperforge paths --json`
  </done>
  <acceptance_criteria>
    - grep finds "paperforge_paths" in ocr_diagnostics.py
    - PADDLEOCR_API_TOKEN env var is used consistently (not TOKEN or KEY)
    - Context: D-04, D-05, D-06, D-18, D-19 from CONTEXT.md
  </acceptance_criteria>
</task>

</tasks>

<verification>
- literature_pipeline.py uses glob("*.json") for export validation
- setup_wizard.py VaultStep Input has value prefilled from app.vault
- ocr_diagnostics.py uses paperforge_paths() for path resolution
- PADDLEOCR_API_TOKEN is consistent
</verification>

<success_criteria>
- SETUP-01, SETUP-02: VaultStep prefill working
- DIAG-01: Doctor validates all *.json exports
- DIAG-02: PADDLEOCR_API_TOKEN consistent
- DIAG-03: Doctor uses paperforge_paths() resolver
</success_criteria>

<output>
After completion, create `.planning/phases/06-setup-cli-diagnostics-consistency/06-02-SUMMARY.md`
</output>
